16

play 如何验证 cookie?

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

cookie 看起来像这样:

PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1

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

来自文档
Discarding the whole session
有丢弃整个会话的特殊操作:

Ok("Bye").withNewSession
4

2 回答 2

11

您没有指定如何对用户进行身份验证,所以我只是猜测,您正在使用简单的示例,它很简单。

它使用用户的 id 来识别用户,并检查签名的会话 cookie 是否未被操纵,因此如果您使用正确的签名重新创建 cookie,它仍然有效。

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

AFAIR 标准内存缓存将在应用程序每次重新启动时被清除,以确保sess_keys从 DB 中删除所有内容,您可以使用全局对象onStart(...)并在方法中截断表。

于 2013-01-31T15:02:10.223 回答
5

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

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


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


所以这就是我担心如果cookie丢失,任何人都可以在未来登录服务器。

我必须做的是添加一个自制的时间戳授权(在 cookie 中保存时间戳并验证服务器端)

于 2013-01-31T14:30:32.423 回答