PHP session expires immediately when client's clock is set in the future

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-23 08:57:53

问题


I have developed this PHP web application which is now running for some months. Suddenly one of the users complained that he was able to login, but the session was terminated as soon as he clicked on any button! The same problem happened on different browsers.

After some tests I realized that a brand new session ID was created every time the user clicked on any button, probably because the original session was expired.

For whatever reason I took a glance at the user's computer clock and... surprise! His clock was 3 months in the future! I didn't know if such thing could have any relation to the failure, but I did fix the clock. Still it didn't work. I erased all cookies. Still nothing. So I restarted the browser - and then it started working again!

The closest information I got about this issue was Shimon Amit's answer to this question. Good, now I know that the clock "misconfiguration" is the cause. The problem is... I cannot keep every customer's computer clock under control. Some of them may have their computer clocks set in the future.

My question: is there any solution for this? Any trick? I don't want customers to face such errors as they may find it "lame" and break their trust on the application, even though it's not really my fault (in a sense).


回答1:


You can extend your session timeout to a later date. Perhaps you can use cookies that don't expire (sessions are related to cookies on the client side) Otherwise, your client's browser is just doing what it's designed to do.

EDIT: Javascript Option

This is a total hack, but you COULD use javascript to get the current time on the client machine and send it back to the server, then adjust the timeout on your session cookie to expire three months after that. See http://www.w3schools.com/jsref/jsref_gettime.asp

Once you have retrieved the client time, you can reset the session expiration using session_cache_expire(). http://www.php.net/manual/en/function.session-cache-expire.php

EDIT: 100% Server Side Option

Another option that I thought of would be to set a session cookie with no expiration, but track the time the cookie was set on the server, say in a MySQL table. You would also need to keep track of the last activity. Whenever a logged in user makes a request, you could check the start time of their session and their last activity. If the current time is greater than your acceptable timeout for either of these, then destroy the session server side and bring them back to the log in page. If the session is still ok, then update the last activity associated with that user so you can compare on the next request. No client side code necessary.




回答2:


Session cookies (like all cookies) are controlled and deleted when expired by the client browser. Even if you set a far out expire date (which you might not want to do anyhow) all the client needs to do is move his clock even farther forward and it will expire.




回答3:


I fully agree with @MarcB's comment that you can't assume responsibility for how grossly misconfigured a user's machine could be. If you really want to make a difference in this regard I would suggest using PHP to output a small snippet of javascript that includes the time on the server. The snippet would compare that time to the time on the client computer and raise an alert if the time differs by more than X from the server. [say, 24hours or so]




回答4:


Any trick?

Use session cookies. Not session in the meaning of PHP sessions, but browser session. Session cookies are stored until the user closes the browser. They are immune to whichever clock the user has set her computer. They will last until the browser is closed.

That is normally appropriate for PHP-session related cookies.

For PHP you need to ensure that the session cookie parameter lifetime is configured to 0 before the session starts. That is either the ini setting session.cookie_lifetime or by calling the session_set_cookie_params function.

For a more detailed description of cookie parameters, see the documentation of the setcookie function.

Second part of the trick is that you place a session start timestamp and a last activity timestamp into the PHP $_SESSION. Those are server based so have always the same base.

Check them, e.g. if the session is too old, last activity too long ago etc., destroy the session and force the user to login again.

You could even use that second part of the trick to combine it with a cookie that has it's expiry 10 years in the future (okay, browser might not like that, maybe you just want your three months).




回答5:


Try to disable the session timeout or at least set it far into the future. That should do the trick.



来源:https://stackoverflow.com/questions/13161398/php-session-expires-immediately-when-clients-clock-is-set-in-the-future

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!