scala Play 框架会话和 cookie 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14627802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:54:32  来源:igfitidea点击:

Play framework how do sessions and cookies work?

javascalaauthenticationcookiesplayframework-2.0

提问by Farmor

How does play validate a cookie?

play 如何验证 cookie?

  • I noticed that after I restarted the server I was still logged in even though I don't presist any session data in the database.
  • I also noticed that I could set the date on the server to be larger that the exipry date of the cookie and still I was logged in.
  • I logged out (saved the cookie to a text file) and the browser lost the cookie. Then I recreated the cookie from the text file and I was logged in again.
  • 我注意到,在我重新启动服务器后,即使我没有在数据库中保存任何会话数据,我仍然处于登录状态。
  • 我还注意到我可以将服务器上的日期设置为大于 cookie 的到期日期,但我仍然处于登录状态。
  • 我注销了(将 cookie 保存到文本文件中)并且浏览器丢失了 cookie。然后我从文本文件中重新创建了 cookie 并再次登录。

The cookie looks like this:

饼干看起来像这样:

PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1

PLAY_SESSION=e6443c88da7xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-userid%3A1

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


From the documentation
Discarding the whole session
There is special operation that discards the whole session:

从文档中丢弃
整个会话
有一个特殊的操作可以丢弃整个会话:

Ok("Bye").withNewSession

回答by biesior

You didn't specify how do you authenticate users, so I just guess, that you;re using simple sample which is... simple.

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

It uses user's id to identify the user, and check if signed session cookie wasn't manipulated, therefore if you'll recreate the cookie with proper signature it will be valid still.

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

You should create some area for session's keys on the server side ie. in DB or in memory cache (Which will be faster than DB). Its key should be randomly generated (and preferebly quite long) for each successful login action, and should also contain data for identifying user, expiration date etc. Next you should put this random sess_keyto the Play's session instead email address of logged user or id of his row in DB, and after logout and/or expiration date it should be removed. In such case even if you'll loose the cookie after logout it will be impossible to login properly with non-esixting sess_key.

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

AFAIR standard memory cache will be purged at every restart of the application, to make sure that all sess_keysfrom DB will be removed as well you can use Global objectand truncate the table in onStart(...)method.

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

回答by Farmor

I found the answer reading the documentationmore carefully and combining different parts.

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

There is no technical timeout for the Session. It expires when the user closes the web browser. If you need a functional timeout for a specific application, just store a timestamp into the user Session and use it however your application needs (e.g. for a maximum session duration, maximum inactivity duration, etc.).

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



It's important to understand that Session and Flash data are not stored by the server but are added to each subsequent HTTP request, using the cookie mechanism. This means that the data size is very limited (up to 4 KB) and that you can only store string values.

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



So that was what i feared that if the cookie get lost anyone can log in to the server for all future.

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

What I have to do to secure this is to add a self-made timestamp authorization (save a timestamp in the cookie and validate sever side)

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