Play框架中会话和Cookie如何工作?

17

玩耍如何验证cookie?

  • 我注意到当我重新启动服务器时,即使我没有在数据库中保留任何会话数据,我仍然处于登录状态。
  • 我还注意到,我可以将服务器上的日期设置为大于cookie到期日期,但我仍然处于登录状态。
  • 我退出登录(将cookie保存到文本文件中),浏览器丢失了cookie。然后我从文本文件中重新创建了cookie,我又重新登录了。

cookie看起来像这样:

PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1

// My logout code
def logout() = Action {
  Ok("").withNewSession
}

从文档中得知
丢弃整个session
有一个特殊操作可以丢弃整个session:

Ok("Bye").withNewSession
2个回答

11

你没有说明如何验证用户,所以我猜测你使用的是简单的示例,也就是简单的方式。

它使用用户的ID来识别用户,并检查签名的会话cookie是否被篡改,因此,如果您使用正确的签名重建cookie,它仍将有效。

您应该在服务器端创建一些用于会话密钥的区域,例如:数据库或内存缓存(比数据库更快)。其键应随机生成(最好相当长),用于每个成功的登录操作,并且还应包含用于识别用户、到期日期等数据。接下来,您应该将此随机的 sess_key 放入Play的会话中,而不是已登录用户的电子邮件地址或其在数据库中的ID,在注销和/或过期之后,应将其删除。 在这种情况下,即使在注销后丢失了cookie,也将无法使用不存在的 sess_key 正确登录。

标准内存缓存将在每次应用程序重启时清除,为了确保从数据库中删除所有'sess_keys',您可以使用Global object并在'onStart(...)'方法中截断表格。

在认证方面,现在只是简单地不参与Play的会话生态系统,这样公平吗?我考虑使用Redis作为半持久性缓存来管理会话ID,并单独使用Play的会话来存储公共会话数据。这听起来像个好计划吗? - Daniel Macias

6

我仔细阅读了文档并结合其中不同的部分,找到了答案。

Session没有技术超时时间。只有在用户关闭Web浏览器时,它才会过期。如果您需要针对特定应用程序设置功能性超时时间,只需将一个时间戳存储到用户Session中,并根据您的应用程序需要使用它(例如,用于最大会话持续时间、最大不活动持续时间等)。


重要的是要理解Session和Flash数据不是由服务器存储的,而是使用cookie机制添加到每个后续的HTTP请求中。这意味着数据大小非常有限(最多4 KB),并且只能存储字符串值。


所以,我的担忧是,如果cookie丢失,任何人都可以登录服务器以获取所有未来的内容。

为了确保安全性,我需要添加一个自制的时间戳授权(将时间戳保存在cookie中并在服务器端进行验证)。


如果 cookie 丢失,任何人都可以登录服务器以供将来使用,这是什么意思?如果没有 cookie,就没有访问权限,这完全是客户端的事情,Play 只确保(签名的)cookie 本身没有被篡改。 - virtualeyes
1
不要将丢失视为空虚,而是看作迷路了。 - user425367
1
将来,请链接到相关文档,以便您的答案读者进一步调查。 - Cheeso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接