【play2.0教程】实现用户登录安全控制


使用play2有一段时间,打算写点使用心得,希望能提高自己的同时也能帮助一些人。

先从用户安全着手吧。每个网站都会用到用户注册,会员分级等功能

1、play2自身的已经提供的API,不过比较简单,先看下API

object Security extends AnyRef

def Authenticated [A] (action: (String) ⇒ Action[A]): Action[(Action[A], A)]

def Authenticated [A] (username: (RequestHeader) ⇒ Option[String], onUnauthorized: (RequestHeader) ⇒ Result)(action: (String) ⇒ Action[A]): Action[(Action[A], A)]

lazy val username : String

API已经提供的基本的功能 我们看Authenticated方法参数, 第一个参数是一个获取用户名的函数,第二个参数是未登录调用的函数,第三个参数是已登录时调用的函数。如果每次写都很麻烦,要传3个参数,大部分情况下未登录都是返回到登录或首页,OK,那么我们可以在其功能上封装一下

2、封装为trait,这样可以方便我们的控制器使用。

trait Secured {

  //第一个参数
  private def username(request: RequestHeader): Option[String] = request.session.get("username")

 //获取用户的详细信息
  def user(request: RequestHeader): Option[models.User] = {
    val user  = request.session.get("username")
    user match {
      case Some(u) => Some(User.findByUsername(u))
      case _ => None
    }
  }

  //默认没有登录的情况下返回登录页面
  def onUnauthorized(request: RequestHeader) = {
    Results.Redirect(routes.UserApplication.login)
  }

  //当用户需要自定义验证失败是调用
  def IsAuthenticated(unAuthorized: RequestHeader => Result)(f: User => Request[AnyContent] => Result) = {
authenticated(unAuthorized,  f)
}
//默认验证失败是调用
  def IsAuthenticated(f: User => Request[AnyContent] => Result) = {
    authenticated(onUnauthorized,  f)
  }

  def authenticated( unAuthorized: RequestHeader => Result,  f: User => Request[AnyContent] => Result) = {
    Security.Authenticated(username, unAuthorized){
      username => {
        var user = User.findByUsername(username)
        Action(request => f(user)(request))
      }
    }
  }
}

上面的已经基本满足我们需求,调用简单,未登录的情况下返回登录页面,如果特殊的需求我们也可以自定义操作。

3、使用封装好的trait

object UserApplication extends Controller with Secured {

  //正常使用
  def fans = IsAuthenticated{ user => request =>
    val rs = Topic.getMyPagination(user.id, 1, 20)
    Ok(views.html.user.fans(Some(user)))
  }
  //使用自定义的验证失败
  def fansCur = IsAuthenticated((request: RequestHeader) => Redirect(routes.UserApplication.register)) { user  => request =>
    val rs = Topic.getMyPagination(user.id, 1, 20)
    Ok(views.html.user.fans(Some(user)))
 }
}

OK,手工。

相关内容