简体   繁体   English

如何正确地重新生成会话ID?

[英]How to properly regenerate session ID's?

I have built a session library, and I am having a very random bug (I don't really know how to unit test this, so I just filled everything with log messages and waited till it happened again) that translates into a user being logged out, due to a session ID mismatch. 我已经建立了一个会话库,并且遇到了一个非常随机的错误(我真的不知道如何进行单元测试,所以我只用日志消息填充了所有内容,等到再次发生时),该错误会转换为正在记录的用户由于会话ID不匹配而退出。

The flow of the application goes like this: 应用程序的流程如下所示:

  • A request with a valid session ID is made 发出具有有效会话ID的请求
  • Session data is found for that session ID in the DB 在数据库中找到该会话ID的会话数据
  • The 'last activity' happens to be old, so it is regenerated and updated in the DB “最后一个活动”恰好是旧的,因此在数据库中对其进行了重新生成和更新
  • The new session ID is sent in the response (as a cookie) 新的会话ID在响应中发送(作为Cookie)

This works fine almost always, but sometimes the next request fails to match the session ID, because (this is my guess) it was sent after we updated the database (in the previous request, which was still running), but before the response with the new cookie came in. 这几乎总是可以正常工作,但是有时下一个请求无法与会话ID匹配,因为(这是我的猜测),因为它是在我们更新数据库之后(在上一个请求中,该请求仍在运行中)但在响应之前发送的。新的cookie进来了。

Did I misunderstand the concept of regenerating a session ID? 我是否误解了重新生成会话ID的概念? I'm regenerating session ID's only for security reasons, so someone that chose to be logged in for a year, still has his session ID changed from time to time. 我仅出于安全原因才重新生成会话ID,因此选择登录一年的人仍然会不时更改其会话ID。

One option would be to keep multiple session ids per user, but put expiry times on them - when it's time to regenerate a session id, add the new one, and put an expiry time on the old one equal to some reasonable period of time (a minute, perhaps). 一种选择是为每个用户保留多个会话ID,但在其上加上到期时间-当需要重新生成会话ID时,添加新的会话ID,并在旧的会话ID上放置一个到期时间,该时间等于某个合理的时间段(一分钟,也许)。 Keep accepting the old one in addition to the new one until the old one expires. 继续接受旧的旧书,直到旧的书到期为止。

I assume you're using session_set_save_handler() , right..? 我假设您正在使用session_set_save_handler() ,对吗? If so, try doing the following: 如果是这样,请尝试执行以下操作:

session_regenerate_id($delete_old_session = true);
session_write_close();

Or even: 甚至:

session_regenerate_id($delete_old_session = false);
session_write_close();

Calling session_write_close() should effectively save the new session data. 调用session_write_close()应该可以有效地保存新的会话数据。 You only have to pay attention when you call this (usually before privilege changes > redirects), since it ends the session. 调用它时(通常在特权更改>重定向之前),您只需注意,因为它会结束会话。


End the current session and store session data. 结束当前会话并存储会话数据。

Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. 会话数据通常在脚本终止后存储,而无需调用session_write_close(),但是由于会话数据被锁定以防止并发写入,因此任何时候任何会话都只能对一个脚本进行操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM