3

我在我的应用程序中使用 Play 框架处理会话,如下面的代码。

def login = Action {
    { implicit request =>

          val email = request.body.asFormUrlEncoded.get("email")(0)
          val password = request.body.asFormUrlEncoded.get("password")(0)

          loginForm.bindFromRequest.fold(
              errors => BadRequest(html.login(errors,"Please enter valid username password")),
              //contact => Ok(html.login(loginForm,SignUpProcess.login(email,password)))
              contact => Redirect(routes.Application.home).withSession("email" -> email,"password" -> password)
          )
      }
  }

  def index = Action { request =>
    request.session.get("email").map{ user =>
        Redirect(routes.Application.home).withSession("email" -> user)
    }.getOrElse{
         Ok(views.html.login(loginForm,"Enter username password to login"))
    }

  }

我需要为我的会话添加超时。在 Play 文档中,

会话没有技术超时,当用户关闭 Web 浏览器时超时。如果您需要特定应用程序的功能超时,只需将时间戳存储到用户会话中并根据您的应用程序需要使用它(例如,最长会话持续时间、最长不活动持续时间等)。

如何在我的用户会话中添加时间戳并设置最大 insctivity 持续时间?

4

3 回答 3

4

通过在 conf/application.conf 文件中设置配置键的值来在 Play 应用程序中配置超时。

application.session.maxAge

会话超时,即会话cookie的最大年龄。如果未设置,会话将在您关闭 Web 浏览器时过期。例如,要将会话设置为一小时:

application.session.maxAge=1h

记住一周的会话:

application.session.maxAge=7d

默认值:会话基于浏览器关闭时过期的临时 cookie。

或者您可以执行以下操作:

在您登录期间,将“最后操作时间”设置为会话中的当前时间。

在您的 Global 类中,如果该标志存在,则覆盖 onRequest 测试

  • 如果没有,用户没有会话 -> 重定向到静默登录

  • 如是

    --- 测试最后一次是否超过 30 分钟前

         ------ if yes, session timeout -> add message to flash, rediect to login   
         ------ if no, update the flag with current time, let the page load
    
于 2013-11-06T10:53:00.823 回答
0

我会这样做如下。在对用户的每个回答中,我都会将当前时间写入会话:

.withSession("currentTime" -> System.currentTimeMillis)

为确保正确的会话时间和电子邮件/密码,我将添加如下Action扩展:

def withEmail(f: String => EssentialAction): EssentialAction =
            Security.Authenticated(
                            currentEmailOpt,
                            r => Redirect(views.html.login(loginForm,"Enter username password to login")) )(f)

private
def currentEmailOpt(request: RequestHeader): Option[String] = 
    for{
      currentTime <- request.session.get("currentTime")
      deltaMs = System.currentTimeMillis - currentTime.toLong
      if deltaMs < 10*60*1000
      email <- request.session.get("email")
    }
      yield email

扩展名的Action使用如下:

def index = withEmail(email => 
   Action { request =>
     Ok(views.html.index(email)).withSession("email" -> email, "currentTime" -> System.currentTimeMillis)
   }
)

(您可以查看https://github.com/Primetalk/todo-list/blob/master/app/controllers/SecuredController.scala及其在https://github.com/Primetalk/todo-list/的用法blob/master/app/controllers/Task.scala)。

UPD:(关于@kliron)以上withSession将取代整个会话。如果您需要在那里存储一些其他信息,那么您需要保存它:

.withSession(session + "currentTime" -> System.currentTimeMillis)

def index = withEmail(email => 
   Action { request =>
     Ok(views.html.index(email)).withSession(session + "currentTime" -> System.currentTimeMillis)
   }
)
于 2013-11-06T19:24:04.653 回答
0

我做了类似@arseniy-zhizhelev 建议的事情

我遇到了同样的问题,并在会话中添加了一个时间戳(滴答声),并在检查超时后用每个请求更新它。

像这样的东西:

// see if the session is expired
String previousTick = session("userTime");
if (previousTick != null && !previousTick.equals("")) {
  long previousT = Long.valueOf(previousTick);
  long currentT = new Date().getTime();
  long timeout = Long.valueOf(Play.application().configuration().getString("sessionTimeout")) * 1000 * 60;
  if ((currentT - previousT) > timeout) {
    // session expired
    session().clear();
    return null;
  } 
}
// update time in session
String tickString = Long.toString(new Date().getTime());
session("userTime", tickString);

http://www.poornerd.com/2014/04/01/how-to-implement-a-session-timeout-in-play-framework-2/

然后将 sessionTimeout=15(以分钟为单位)添加到您的 conf 文件中。

于 2014-04-01T19:51:29.827 回答