1

Play2のzentasksの例では、メソッドがあります

def isAuthenticated(f: => String => Request[AnyContent] => Result) = {
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }
}

私がやりたいのは、データベースから直接ユーザーを取得したい場合に使用できる別のメソッドを追加することです。

すべてのメソッドにラッパーを追加する必要があるのは少し退屈です

def method() = isAuthenticated { username => implicit request =>
  UserDAO.findOneByEmail(username).map { user =>
    Ok(html.user.view(user))
  }.getOrElse(Forbidden)
}

私は関数型プログラミングに不慣れであり、これらすべて=>が私の頭を回転させています:)

助言がありますか?

4

3 に答える 3

5

たとえばIsAuthenticatedUser、次のタイプのパラメータを受け取る別のメソッドを定義できますUser => Request[AnyContent] => Result

def IsAuthenticatedUser(f: User => Request[AnyContent] => Result) = IsAuthenticated { email => request =>
  UserDAO.findOneByEmail(email).map { user =>
    f(user)(request)
  }.getOrElse(Forbidden)
}

その後、次のように使用できます。

def method = IsAuthenticatedUser { user => request =>
  Ok(html.user.view(user))
}
于 2012-04-13T20:53:01.730 に答える
4

これが最終的な解決策でした

trait Secured {

  def username(request: RequestHeader) = request.session.get(Security.username)

  def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login)

  def withAuth(f: => String => Request[AnyContent] => Result) = {
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
  }

  def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request =>
    UserDAO.findOneByUsername(username).map { user =>
      f(user)(request)
    }.getOrElse(onUnauthorized(request))
  }

}

使用法:

object Application extends Controller with Secured {

  def index = withAuth { username => implicit request =>
    Ok(html.index(username))
  }

  def user() = withUser { user => implicit request =>
    val username = user.username
    Ok(html.user(user))
  }
}

ご覧のとおり、セッションが存在しない場合、ユーザーはトレイトで指定されているログインページにリダイレクトされます。

また、DAOでユーザー名が見つからない場合も同様です。

于 2012-04-14T07:00:27.590 に答える
1

セミソリューションは、すべてのテンプレートが単なるscala関数であるため、ユーザーデータステップのフェッチをいくつかの関数にカプセル化し、テンプレートレベルから呼び出すことです(各アクションではありません)。

このアプローチのおかげで、同じビュー(またはレイアウト)を使用する複数のアクションがある場合、ログに記録されたユーザーを毎回フェッチする必要はありません。

user view

@defining(Application.getLoggedUser){ user =>
    @yourlayout("Welcome") {
        <h2>Hello @user.name</h2>
        ...
    } 
}
于 2012-04-13T16:29:26.383 に答える