I'm having a small bit of doubts here as to how sessions should be handled.
Right now, I have a MySQL database where the "users" table has a field for session_id. If NULL, the user is not logged in? If the value is the same as the value of the PHPSESSID cookie, than the user is logged in.
I don't know why, but I somehow feel this isn't good enough a way to make sure which user I'm dealing with. Is there something I'm missing, or do my fears hold no ground?
There's nothing essentially wrong with what you describe as far as I can see.
Of course, your login and logout mechanisms need to reliably add and remove the user ID when logging in or out. (insert a user name only when passwords match, etc) . Also, expired sessions need to be removed reliably. If that is given, this should be fine.
Just an extension on what Pekka said, you could also include a 'last seen' field into your table and use that as a judge because as Pekka mentioned about expired sessions, your database won't be informed that they are gone. So you will be forced to either make something so it manually checks the last time a user was there or something along those lines and then map that back to the session timeout (which I believe is either 15-30 minutes by default for PHP) and then after said amount of time, clear any of the users who haven't been active within the last X minutes.
A thought of the options above - tracking a user in the user table would only allow 1 session per user. I suggest storing the data in a table called sessions and have these columns:
sess_id | sess_userid | sess_ipv4 | sess_lastseen(datetime/timestamp) | sess_sessionid (varchar)
I believe that will allow user to have multiple logins, but with different session id's, even if they share the same public IP, allowing a laptop, tablet, phone etc - this way u can track each device separately from a single user.
hope this helps!
Another post ir read last week suggested having a prevsession and currsession and making sure u are assigning a new session (every 15 mins?) to the correct user. . swapping the sessions from old to new and storing the prev session as a check - not sure if this would help but thought id mention it.
Related
I was wondering if I could determine if someone's session has been ended and if I could do something if it has.
So for example, if session has ended set player status to offline.
If a user does not make a request to the server you cannot reliably know when their session has ended unless you use a database system. For example, you have a sessions table:
session_id | user_id | session_start_time
Whenever you load a page you look if a session_start_time is old enough to be deleted. For example:
if (($data['session_start_time'] + USER_SESSION_TTL) < time()) {
// delete row
}
USER_SESSION_TTL is the time that the user's session stays alive if he is inactive.
Now if the user does not have a session associated with him, you can safely assume he is offline. I generalized a bit, but it can be applied to many systems.
Hope this helps
There is no built in mechanism for this, though, if you implement your own session handler, you can probably do something about it.
See http://nl2.php.net/manual/en/function.session-set-save-handler.php for some ideas.
I got a problem, when the user is logged, and I assign the user their id, for example, 126. But when I doing maintain, or delete some banned user, for example, the user id 126 will remove from the database, but the user 126 still have the number 126 in his session. How can I 'delete' his session content when I detect my database have user id is deleted? Thank you.
Sounds to me like you are worried about ID 126 being blocked even if it gets assigned to a new user.
Shouldn't be a problem, cause IDs in those cases (usally) get created in an auto increment fashion and the DB (MySQL for sure, most others probably, too) chooses the next higher value to the highest ever generated value in such an auto-increment field.
So if the highes assigned value was 1234, then you can delete what you want, the next value is going to be 1235.
So your problem is not really a problem as it seems to me.
There are 2 solutions that I can think of this,
1.) Store the user credentials in the db,
every time the user makes an action you can check for credentials then kick the user out if already banned. I don't think its
2.) cache the logged in users, the cache should be global so the banned user's session can be checked
I have a project where I would like to create two session cookies in one browser. The first session would be to uniquely identify a person, the second would be to share events within the session between users. I have been using a database for this, but would like the data to disappear when the session dies. There are no logins within the system.
Is there a way to do this, other than creating a cookie system to replicate functionality?
For example, we would have two session cookies:
name=someRandomUUID and session=valueSharedBetweenUsers.
I don't want to share the name session with multiple users, but the session session would be. Thoughts?
If you want to share information between users, using a session is not the best idea as it uses the file system. You would be better off using the database which handles all the issues of locking, concurrency etc.
Although what you ask for is technically possibly, I would strongly recommend against it.
EDIT
Assuming I have understood your requirement correctly, here is how I would do it:
Use session only to store session data related to that user. It could include something like:
$_SESSION['name'] = 'test name';
$_SESSION['groupid'] = 2;
A MySQL DB and table with fields groupid, XXXXX (data you want to store), timestamp
Whenever anyone updates information for a particular group id, you update the timestamp.
Then run a simple cronjob to check if any current time - timestamp > 3600 (one hour) and you can consider that as stale and delete those records.
I *think* you can only have one "current" session, but the functionality you are referring to is session_name:
http://www.php.net/manual/en/function.session-name.php
The cookie functionality is very simple. I suggest looking into that instead.
Where is the "valueSharedBetweenUsers" coming from? Is it a constant or database entry?
Either way, it wouldn't make sense to create one session per group. You should instead be giving each user a unique session per user; with your "shared" attribute as a session attribute for each individual.
So start the unique session then just do <? $_SESSION['session'] = 'mySharedValue'; ?>
Now everyone has a session with a unique sessionID and a common value 'session'.
(Obviously if you need to change this attribute later you'll have to do it separately for each authed individual)
This isnt as far fetched as people are making facebook and twitter have at least 10 different sessions being created when a user has logged in.
A feature that is currently missing from one of my web apps is that a single user can only be logged in on one machine at a time. That is, if the users logs in elsewhere, his previous session will be logged off.
This is due to my current users table having the columns:
user: id, username, hash, salt... cursession
When each user logs in, the session ID is put into the "cursession" field and on each page-load, is checked against the database. As a result, only one "session" can be active at a time.
Is the current table structure and method secure and standard? This system was pretty much improvised, and I have no professional experience.
What would be a way to allow multiple simultaneous logins? I'm simply thinking of adding a "sessions" table with more userid-cursession relations, but what's the standard method for doing this?
I propose that you put the current logged in userid in the user's session (as a session variable), and drop the cursession field from the table altogether. You don't need to reinvent session handling since PHP already has it built-in.
That way the user can be logged in at multiple computers at once. Session variables are safe too, since they're not manipulated by the browser. The only thing kept in the browser is a session id which identifies the current session, all other data is stored on the server-side. The only thing that will happen if the user changes his browser cookies is that he will be logged out (start an empty session), so he can't force himself to log in as someone else.
I'm working a site where users could technically stay logged in forever, as long as they never close their browser (and therefore never get a new session key). Here's what I could see happening: a user leaves a browser open on computer A. The then use computer B, login and change their name which is stored in the session. They logout of B, but A is still logged in and still has their old name stored in the session. Therefore, their name won't be updated till the next time they logout manually or they close their browser and open it again and are logged in through the remember me function.
Name is a simple example, but in my case the subscription level of their account is stored in the session and can be changed.
How do you deal with this?
A few ideas that I have are:
After a period of 10 minutes or more, the session data get's reloaded. It might be exactly 10 minutes if the user is highly active as the function will get triggered right at the 10 minute point or it could be after 2 hours if the user leaves and comes back and then triggers the functionality.
Store as little information as possible in the session and load the rest from the DB on every page call. (I really don't like this idea.)
Use database sessions and use the same session on all the computers. I like this, but I could see it getting confusing when something like search criteria are stored in the session--the same criteria would show up on both browsers/comptuers.
For information, even such as the user's name or username/email address, store it in the session, but for other information that would heavily affect their abilities on the site, don't store it in the session and load when needed (attempt to only do it once per instance).
Are there other better methods?
--
Another option: 5. Use database session and when an update is made load the user's other sessions (just unserialize), change the relevant information and save them back to the database.
I would go either with number 1 or number 4. If you store the time of the last update of the information, you could even ask on every request whether the date has been updated.
Don't store information likely to change in the session, if you're looking at scenarios like the one you outline. Just get over your dislike of loading user data with every page - it's by far the best idea.
I'm guessing you don't want to load the data from the database because you're concerned about performance issues somehow. Before you try out any of the other solutions, you might want to test how long it takes to actually load a users data from the database, then check that against your number of users - chances are you won't see any performance problems due to loading user profiles on every page.
Regards
I'd go with option 6: only store userid and session specific stuff (search criteria) in his session and put the rest into APC/xcache (memcached if you're using multiple servers).
this way you'll only have to go to the database the first time (and after the cache expires) and you can still share any data between users sessions.
Normally you should do 2), but you don't like it.
maybe you can use sessions stored in db.
when a user change his name, put into all sessions from that user the information "refresh userdata".
on the next request the userdata is reloaded again into the session and is cached there.
this can be done be reusing your loaduserdata function which called at login.
php session_set_save_handler() - also read comments
php session_decode() - to read the username from the session to store it additionally to the sessiondata. usefull for easily to find the users sessions for updating.
[edit]
don't forget:
when you are updating all the sessions while the page is generated (between session_start and session_write_close) you changes maybe lost.