2013-05-13 29 views
1

我正在使用Play Framework(Scala)和SecureSocial來驗證用戶身份。安全社交遊戲2.x /保持暫時性,未註冊(即尚未登錄)會話中的用戶?

我希望我的網站允許用戶在他們的會話期間瀏覽和填充某些用戶數據(例如電子郵件地址)。

我有一個持續存在登錄的用戶(實現securesocial.core.Identity特質和我自己的User模型對象)的DB

我有一個UnregisteredUser子類,我想其中一個自定義的UserService實現在用戶沒有登錄的時候堅持在會話中。

請問這樣做的最佳做法是什麼?

回答

1

我想你的特定目標是在每個感興趣的控制器的操作中有效地收集與未註冊用戶相關的全部數據。 問題:我們想要檢索構建UnregisteredUser,直接在會話中收集所有這些數據。

首先,堅持了UnregisteredUser數據每當你使用基本播放2的API Sessions會話想:

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特質兩個用戶樣式。 因此,你必須覆蓋UserAwareAction延長SecureSocial你的特點,以功能相結合:

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 
    } 
} 

當然,你可以自由地重構它:)

+0

我試圖實現您的解決方案我們會說,並且敏銳地看着你的編輯,因爲我對Play很新穎,額外的解釋非常感謝 – 2013-05-13 11:39:23

+1

@Chris Beach我剛剛更新了我的答案。 – Mik378 2013-05-13 11:40:20

+0

我很想擁有一個用戶對象層次結構,該層次結構包含一個抽象超類,該超類包含諸如電子郵件和UnregisteredUser和RegisteredUser(包含數據庫ID)的子類的字段。我希望我的控制器方法能夠期待一個User子類,使我能夠與註冊和未註冊的用戶同等操作。我目前正在使用由SecureSocial提供的UserAwareAction包裝。有沒有辦法將你的GuestAction與此綁定,所以在我的控制器方法中,我得到一個User子類,無論它來自SecureSocial還是來自GuestAction會話對象? – 2013-05-13 11:41:38

相關問題