我正在使用Play Framework(Scala)和SecureSocial来验证用户身份。
我希望我的网站允许非 -logged-in用户在会话期间浏览并填充某些用户数据(例如电子邮件地址)。
我有一个自定义UserService实现,它将登录用户持久保存到DB(以及我自己的User
模型对象,该对象实现了securesocial.core.Identity Trait)
我有一个UnregisteredUser
子类,我想在用户未登录时保留在会话中。
请问最佳做法是什么?
答案 0 :(得分:1)
我认为您的特定目标是在每个感兴趣的控制器操作中有效地收集与未注册用户相关的整个数据。
问题:我们想要在会话中直接收集所有这些数据的构建UnregisteredUser
。
首先,使用基本的Play 2的api Sessions在会话中随时保留UnregisteredUser
数据:
Ok("Welcome Guest User!").withSession(
"email" -> "unregisteredUserEmail" // assuming a randomly chosen Id since not logged yet
// many other data here
)
然后,您可以简单地写一个trait
来扩展您的实际SecureSocial
特征,其中包含:
case class GuestRequest[A](optUnregisteredUser: Option[UnregisteredUser], request: Request[A]) extends WrappedRequest(request)
def GuestAction(f: GuestRequest[AnyContent] => Result): Action[AnyContent] = {
implicit request => {
val optUnregisteredUserEmail = session.get("currentUnregisteredUser")
val unregisteredUser = UnregisteredUser(optUnregisteredUserEmail)
f(GuestRequest(optUnregisteredUser, request))
}
在您关注的每个控制器中,您只需执行以下操作:
def addToCard = GuestAction {
implicit request =>
val currentUnregisteredUser: UnregisteredUser = optUnregisteredUser.getOrElse(.....)
//remaining instructions here
}
<强> -------------- UPDATE ------------- 强>
实际上,您可以使用现有UserAwareAction
特征的SecureSocial
作为两种用户样式。
因此,您必须覆盖扩展SecureSocial的特征中的UserAwareAction
,以便组合功能:
override def UserAwareAction[A](p: BodyParser[A])(f: RequestWithUser[A] => Result) = Action(p) {
implicit request => {
val user = for (
authenticator <- authenticatorFromRequest;
user <- userServices.findByUserName(authenticator.userName)
) yield {
touch(authenticator)
user
}
if(user.isEmpty){ //meaning user is not logged
f(RequestWithUser(tryToBuildUnRegisteredUser, request)) //setting your unregisteredUser
}
else{
f(RequestWithUser(user, request))
}
}
}
private def tryToBuildUnregisteredUser = {
val optUnregisteredUserEmail = session.get("currentUnregisteredUser")
optUnregisteredUserEmail match {
case Some(e) => Some(UnregisteredUser(e))
case _ => None
}
}
当然,你可以自由地重构它:)