PHP session - multiple sessions per user - how to sync? - php

I'm storing some user information in session so I don't have to query the database every single time user changes page. What if this user uses multiple browsers/computers and olders sessions have invalid data now? How do I keep them in sync? Logging out the older sessions of the user is fine, but I would like to avoid writing session info to db, if possible.
I do realize it's a fairly common problem, but I couldn't come up with right stuff after googling.

Store the session in a database for each specific user.
Then each time the users access your site (regardless of which browser) - all the information is always in one location, and you dont have to do any fancy 'sync' stuff.
Note: they will still have to 'login' from each different browser. During the login process, you will need to check if a session already exists in the database for that user. If it does, you need to attach this new login to that session (rather than create a new one).

Related

Codeigniter sessions queries with multiple users and repeat logins

A few questions before I start my project in Codeigniter
How long does Codeigniter store the data in a session table for a particular user. Is it as long as he is logged in?
How can I modify the schema of the sessions table, I mean modifying the datatypes of the already present schema.
Above question brings me to another one, can i change the Session table schema itself?
Can I put in multiple cookies on the user's browser through a single session ID.
How can I access the Session table through MYSQL console or is only accessible through the Codeigniter
When the user logs in to my website again, how are the cookies from my website stored during the user's previous login get available to me for reading. How can i read them?
I know this might have been asked in bits and peices before but I wanted to have a clear picture in mind before I start my project. Thanks in advance
Codeigniter actually uses cookies for their sessions and you set the expiry time in the config.php file. I am not really sure how long it stores the actual database info (It isn't that long) and it will rewrite a new entry for a user when they log back in. So it's not really recommended to store critical data in the session table itself that isn't stored elsewhere. As long as their cookie persists the information could be restored but if they delete the cookie then you'll lose that data. If you need to store something permanently on a user don't use the session table.
I have no idea why you'd want to change the data types of the already present schema and honestly that would very likely screw up the system being able to store that data anyway without extending the session library. This seems like a huge headache to me for no real value.
Answered 3 already, don't add to the schema, create a new table if you need to store more info.
As to 4, 5 and 6. Since CI uses cookies for it's sessions anything you store in the session is a cookie and will be there until it expires or the user deletes their cookies.
Save info to the session:
$this->session->set_userdata('some_key','some value for that key');
Retrieve it:
$data = $this->session->userdata('some_key');
Read more here: http://ellislab.com/codeigniter/user-guide/libraries/sessions.html

What is the best: Check the database or just check the session on each page using PHP

I've developed many login systems in PHP. Basically, for each website or application I created, it had a login scheme to create articles, upload images, edit comments e blablabla.
I've never had problems with that, except once when I created a kind of social page inside my website. There was a user bothering the other users, so I decided to delete his profile, that's why I'm here asking your help.
At the time, I was just checking the session on each page, for example:
<?php
if($_SESSION['loggedin'] === true)
{
// Keep that page
}
else
{
// redirect to login page
}
?>
Then, when I deleted his profile the session wasn't closed yet, after that the user continued annoying the other users, and I wasn't able to do anything.
So, what's the most common and best way to handle sessions on each page: Check the database each time or just check if the session is true?
I don't know whats the best way, but I do something like this:
I have an sql table with the sessions (for example userid, sessionid, expiredate, ...).
The sessionid is "saved" in a $_SESSION['cms_session'] .
If the sessionid which is in $_SESSION['cms_session'] doesn't exist in the session table, the user isn't loged in anymore.
For deleting the old sessions in the table i use crons.
What you are trying to do is have a single place where you can maintain user status and know that a change will be reflected immediately.
Checking a "user_status" field in the DB is a pretty efficient call to make on each request. This provides a single place where you know that if you deactivate a user, the changes will be reflected upon their next request. You can also do this easily without writing another set of routines to look through session variables or to create some sort of messaging system where the application announces that a user has been deactivated.
Checking the database each time a page loads is really inefficient. If all you're trying to do is kill his session, you should store sessions in memcached where the 'key' is based on the username, something like "johnsmith-session" and then on an admin page, send a message to memcached to kill that key, which should immediately log him out of your site.
If PHP is currently writing session data to disk, depending on how the data is serialized, you may be able to track down his session file on disk and delete that file, which will accomplish the same thing: the next time that user tries to load a new page, his session will be invalid and he'll be required to log in again.
Keep in mind that really persistent trouble users will often re-register a new account to continue their antics, so you'll want other means of watching for new registrations from that person.

Maintaining a single logged user into an account in php

I want to make a login system using PHP and MySQL and do it in such a way that every-time only one person is logged into my system at any point of time. If the same user logs in on another window/session/place the old running instance should be invalidated and the new one should be validated.
I am aware that I can get this done by storing the session-id in the database and some routine that checks it and keeps on verifying it constantly periodically or on any database action.
Is there any other way I can accomplish this so that the checks for verification are minimized and I don't have to fire a query on each page refresh to check if the user is in the last logged valid login session.
In short I can summarize that i need a technique so that only my last valid login browser window is served the webapp.
You don't need to have any polling method, in fact you all you need to do is store the session id of any logged in user along with their username in a database.
Then, on each login, simply check if the user logging in already has a stored session. If they do, invalidate that one and store the newly logged in session in a database.
When an old session tries to reconnect to the app, the data for their session will no longer be stored on your server, so they won't be logged in any longer.
All this requires is making an extra check anytime somebody logs in, not any polling method or the like.
Every time the user loads a site of your homepage you have to check whether the user is logged in or not. This is always one sql query. So store the session-key along with the user-data and than you can simply add the session-key to the WHERE-clause to identify the user. In this way you have only your one sql query which you have anyway to verfiy that the user is logged in.
Firstly, I'd build this with a database to manage your session policy. If it turns out to be bottleneck, you can optimise then.
If the application runs on a single server, you could perhaps use shared memory (e.g. using APC's apc_store & apc_fetch) to store some state information which can be shared among processes. This could simply store the last-known session id, keyed on the user id. Then you can quickly discover if the current session is still valid.
If you're running on multiple servers, then memcache might be worth a look for achieving something similar.

same logged in user assigned different session ids (in different browsers)

I've implemented a mysql-based session interface in php.
I just found out that if I log in to my account using browser A (e.g. Chrome), and then I log in to the same account in another browser B (e.g. IE), each browser is assigned 2 separate session ids. How can I make it such that when I log in again using browser B, I retain the active session of the previous browser A?
The issue at hand is that I'm storing certain information in the session and the data not being synchronised between the same users in different browsers and is wrecking havoc. :S
Is there a way to achieve this?
Thanks!
If you're storing the session in the database, add a mechanism whereby the userId is stored as part of your database's session record, creating what I like to call a "semantic session". When the user logs in, check to see if another session already exists; if so, use session_id() to fixate the new session to the old session's ID, which will join them (and should change your new session's ID for all subsequent requests). Be sure to only perform this action during the login step, or you might end up with freaky race conditions of two sessions trying to be each other and "swapping".
Don't store the data in session, store it in the database.
Sessions are normally identified by cookies, which are only visible in one browser. You could probably use Flash to share the session ID between browsers, but I cannot think of a use case. The point of the session is to store data which is bound to a single browsing session, and not to the user in general. You should use a database or some other form of server-side storage for generic user data.

What is the best way to deal with sessions when the user may stay logged in, but a session key needs to be updated, because of another update?

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.

Categories