Yii Session Timeout and Periodic Server Short Polling - php

I am using short polling in jQuery to periodically (5 mins) check the server for notification updates. I also have a session timeout set on the server after which i would like the user to get automatically logged out. The trouble is that the polling causes the session to extend and the user never gets automatically timed out.
Is there any way in Yii to avoid updating the session for this call alone? Am I missing something?
I am thinking of moving the server side script for this call alone to a standalone PHP script but there would be maintenance overhead associated with this so I am kind of hoping that there is something I can do within Yii to work around this. Thanks.

I suggest to have a session variable for last time of activity
, every time an activity that counts as an activity, update this
and in case of this special request, don't update this and check if the time period is over, manually log user out and destroy it's session
Yii::app()->user->logout();
unset($_SESSION);

Related

How to close a session in PHP when the browser is closed?

I need to close a session when the browser is closed, when it crashes, when a PC restarts, and so on.
I know there is cookie solution, but I need something secure, server side, because the user can delete the cookie.
You dont have to. The garbage collector will clean up your sessions.
The php ini setting session.gc_maxlifetime determins how long a session can remain active.
When this value is exceeded the session is automatically removed.
This can not be done the way you imagine it.
You can not directly react to such an event in php.
The closest you can get is using ajax to keep the session alive.
Create a small php script which does nothing but update $_SESSION['last_request'] lets call it pulse.php
Insert a javascript in you pages which sends a request to
yourdomain.com/api/pulse.php every 60 seconds.
Check if the last request uis older than 70 seconds on every request
if it is start your clean up script and kill the session.
If the browser crashes your cleanup script will not run. The session will timeout the usual way unless you get a request after more than 70 seconds but before the session expires.
You can fix this if you store the session data in a database.
Then you can run a worker or a cronjob which regularly checks if there are sessions where the last request was more than 70 seconds ago.
Why 70 seconds? If you expect a request once per minute you should allow some time for klatencys or slow hardware on the client side.
Hi You don't need to close session. because its default behavior of session that it destroy the session when user close the browser. And we can alter this behavior by changing lifetime of session in php.ini file by doing
session.cookie_lifetime = 0. Otherwise by default
when you reopen the browser there will be no data in session.
cookie delete automatic when user run crashed brouser.
in php no way to know when user close brouser.
some not easy way it's websocket and long poling connections, but it's not easy to configuration and not good idea.

Can't have several threads per session

I am buidling some webapp and have implemented long-polling (and a command queue in my db) so my server can send commands to my cleint asynchronously, etc. The commands are encoded into json and sent over ajax calls for the client to server, and via long-polling for the server to client way.
Everything was working just fine, until I included my "Authentication module" in the ajax.php file. This module wraps the session stuff and calls session_start().
The problem is that, my long polling routine can wait up to 21 seconds before comming back to the client. During this time, the server won't run anything from the same session. It's instead executed right after the long polling ajax call returned.
I understand there's probably a restriction of only 1 thread per session at a time, and that the requests are queued up.
Now here's the question : What is the best way to address this? Is there a setting to allow several threads per sessions (3 would be fine, in my case). Or should I just send tell the client what is his SessionID (i have some sessions table in my db, to track which user is connected to which session(s)). The client could then send it along with any ajax calls so authentication module could be bypassed.
On the later option, iam afraid it open's up a bunch of security problems because of eventual session spoofing. I would need to send a "random string" to each session, to make sure you can't spoof too easily, but even then, it's not perfect...
Thanks for your awnsers :)
Nicolas Gauthier
It's a well known issue/fact that PHP locks session files for the duration of their usage in order to prevent race conditions.
If you take a look at the PHP source code, (ext/session/mod_files.c) you can see that the ps_files_open function locks the session file, and ps_files_close unlocks it.
If you call session_start() right at the beginning of your long-running script, and do not explicitly close the session file, it will be locked until the script terminates, where PHP will release all file locks during script shutdown.
While you are not using the session, you should call session_write_close to flush the session data to disk, and release the lock so that your other "threads" can read the data.
I'm sure you can imagine what would happen if the file was not locked.
T1: Open Session
T2: Open Session
...
T2: Write Data
T1: Write Data
The data written by thread 2 will be completely overwritten by thread 1, and at the same time, any data that thread 1 wanted to write out, was not available to thread 2.

implementation of ajax status check

I am battling with race condition protection in PHP.
My application is written in symfony 1.4 and PHP locks session data until a page completes processing. I have a long running (~10 second) login script and I want to display a progress bar showing the user what is being done while they wait. (I want to actually display what is being done and not use a standard [faux] loading bar.)
Whenever a script calls session_start(), PHP locks that user's session data until that script completes. This prevents my status check ajax calls from returning anything until the longer running script completes. (My question on why my ajax calls were not asynchronous is here.)
I have devised a way to do this but I want to make sure this way is secure enough for general purposes (i.e.- this is not a banking application).
My idea is:
On authentication of username & password (before the long login script starts), a cookie is set on the client computer with a unique identifier.
This same unique identifier is written to a file on the server along with the client IP address.
While the long login script runs, it will update that file with the status of the login process.
The ajax status check will ping the server on a special page that does not use session_start(). This page will get the cookie value and the client IP and check the server side file for any status updates.
Are there any glaringly obvious problems with this solution?
Again, from the security angle, even if someone hacked this all they would get is a number representing the state of the login progress.
I don't see anything inherently wrong with the approach that you are proposing.
But if your machine has APC installed you can use apc_store and apc_fetch to store your status in a sort of shared memory instead of writing to disk. Use something like apc_store(SID, 'login not started') to initialize and update the request state in memory, then apc_fetch(SID) to retrieve it on subsequent requests.
There are other shared memory systems, including Apache, or even a database connection might be simpler.
I have same problem and think the trick is session_write_close() that frees the session file.
Please see my https://github.com/jlaso/MySession repository and check if this can be apply to your particular question.

PHP Session expire event

I am trying to make some changes to an opensource project. I want to keep track of when users log in and log out.
Right now I change their login status in db when they login or manually log out. The problem right now is that I cannot find out if the user just closed their browser without pressing on logout button.
For this reason I need to trigger a function that will change database every time the user's session expires.
I've tried session_set_save_handler in PHP, but it looks like I need to override the whole session behavior. What I am looking for is to keep default session behavior and just add functionality when the user's session expires. Is there a way to do that?
I did something really nasty once. Every time a session was "updated" by a page refresh / fetch / etc., I updated a timestamp on a DB row. A second daemon polled the DB every 10 minutes and performed "clean-up" operations.
You won't find any native PHP facilities to achieve your goal. Session timeout doesn't run in the background. You won't even know if a session is timed out, unless a timed out session attempts another access. At this point, nearly impossible to trap, you can make your determination and handle it appropriately.
I'd recommend a queue & poll architecture for this problem. It's easy and will definitely work. Add memcached if you have concerns about transaction performance.
I presume you're using standard PHP file-based sessions. If that's the case, then PHP will do its own garbage collection of stale sessions based on the session.gc_* configuration parameters in php.ini. You can override those to disable the garbage collector completely, then roll your own GC script.
You could either check the timestamps on the files (quick and easy to do in a loop with stat()) to find 'old' sessions, or parse the data in each file to check for a variable that lists the last-access time. Either way, the session files are merely the output of serialize($_SESSION) and can be trivially re-loaded into another PHP instance.
What about window close event on javascript. So basically session is destroyed when all of the windows of the session site are closed. So, when the last window is closed ( this is checked via additional js checking ) send ajax request to server.

Session_set_save_handler close/gc

I need to perform an action after a session times out. However I have no clue how to trigger that action without an incoming request. An event handler/a listener/a timer would suit perfect but since PHP does not support such a thing it is really difficult to accomplish what I want.
After lot of searching I bumped into session_set_save_handler but I still cannot fully understand how this method works. If I write code that triggers the action inside the close method when it will be executed?
I also need to keep the current session solution as it is and I wonder what the ramifications of using session_set_save_handler in conjunction with that will be? (My current solution sets a session cookie, assigns a name to the session and starts the session, when the user logs out or a request is done after the session timeout (that value is set in a configuration file) the session is completely destroyed)
Regards!
This is somewhat difficult to do in php, AFAIK.
But you can try by making a passive session handler:
Store session ids associated with a timestamp.
Each time the user associated with certain id makes a request, refresh it's timestamp.
You can detect defunct sessions by comparing the system's current, and each session id's timestamps. The ones that differ above a given treshold (say 30min), are assumed to have passed away. Then you can execute your own save handlers for these session ids.
This won't work if the session end handler needs to be executed inmediately, as this process is executed each time when a request arrives (from any user), so it will depend directly on the website's traffic flow.
But you can also solve it by setting cron jobs each 15min or so. Depending on how expensive your save handlers are, seems an acceptable periodicity.
PHP needs to run in some way for PHP code to execute. Either through a user request or a cronjob.
A Session is saved to the locale storage when a PHP request finishes executing or when session_write_close() is called
This session_set_save_handler() allows you to write your own save handler.

Categories