这是一个Play 文档中的授权示例 https://www.playframework.com/documentation/2.0.4/ScalaSecurity#Authorization(版本 2.0.4;我试图找到此文档的更新版本,但找不到):
trait Secured {
def username(request: RequestHeader) = request.session.get(Security.username)
def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.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))
}
}
总的来说,这非常简单,我想采用这样的方法。
现在,在 Play 2.4 中推荐的方式是not不再使用单例(如上面的 UserDAO),而是使用类和运行时 DI(参见迁移指南 https://www.playframework.com/documentation/2.4.x/Migration24#Dependency-Injection, or DI docs https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection).
例如,我的服务和存储库类定义如下:
class AuthService @Inject()(accountRepo: AccountRepository) { }
class AccountRepository { }
使用 Play 2.4 和 DI 时,获取服务或 DAO 的推荐/“正确”/最简单方法是什么(例如AuthService
就我而言,或者UserDAO
在文档示例中)在类似的特征中Secured
?
或者你现在是否应该以一种完全不同于使用这种特征的方式来实现控制器的授权?
我可以让它按照以下方式工作:
trait Secured {
val authService = GuiceUtils.inject[AuthService]
// ...
}
使用这样的助手:
object GuiceUtils {
lazy val injector = new GuiceApplicationBuilder().injector()
def inject[T: ClassTag]: T = injector.instanceOf[T]
}
但根据a中的回答相关问题 https://stackoverflow.com/a/31937794/56285:
在Play中你可以直接使用注入器,只要应用程序
特质在范围内。但这不被认为是好的做法
生产代码。
如果这是真的,那是什么is在这个用例中被认为是好的实践吗?