I have php login page that stores the user id in the session once the login is successful. User can navigate to different pages or can even close the page briefly and once user re-open the page, he is still logged in. However the problem is that when the user closes the page for longer time, the session get expired automatically and he has to re-enter the credentials and login again.
How can I keep the user logged in forever and log out ONLY if user decides to do so?
I would like the user to be able to close the page, turn off the pc for weeks and when he or she comes back to visit the page, he or she should be already logged in.
Sound like you need to set the cookie expiration date - as per this wikipedia article on HTTP cookies, if you do not set an expiration date for a cookie it becomes a session cookie. i.e. it expires once the browser closes.
There is no real way to specify that a cookie NEVER expires, however you can set the expiration date for some time far in the future.. i.e. in 10 years, and renew that expiration date every time the user loads a page.
setCookie( name, value, expiration )
Another alternative (which would also require some JS on your pages) would be to use the browser's internal database to store the user session id so that you can retrieve the session from your database (I assume you are using some sort of database, otherwise you will run into other issues as explained below).
If I wanted to achieve this I would probably have a piece of javascript on my page loads that checked for the existence of the session cookie, and if not, I would load the session id from the browser's database, drop the cookie, and force a page reload. There are certainly more elegant ways of achieving this, but this should give you an example of how to get this started.
Lastly, please keep in mind that if you don't use a database (i.e. Redis, Memcached, SQL), all you session information is lost when you restart your application server. This is certainly suboptimal, and you should store session information in a database if you want to have this information survive server restarts (or if you have a load balanced environment).
Hope this helps!
Related
I have read many answers on stackoverflow, but none of them could answer my question.
Let's consider a case, where a teacher and the student use the same computer. The teacher uses it to upload marks and the student use the computer to browse the marks. Now, the cookies of the teacher are stored and accessible. The student can easily forge the cookies and present himself as a teacher to the system and create havoc.
What approach should I take to disable this? Is this only possible via sessions? Or there exists a possibility with cookies as well.
The main two suggestions I would have are:
Delete the entire session right before the user logs out or logs in. A new session should always be started when authorization level changes.
Only accept sessions ids you generate. By default PHP will accept and start a new session for any value of the session id you send it. If you receive a session id you haven't seen before, discard it and send the user a new one.
If it's not necessary to have the browser remeber the cookie between browser sessions (eg a login can be 'forgotten' if the browser window is closed), then you could NOT set the expiry date on the cookie which makes it memory-resident only.
When the user closes the web broswer, the cookie is forgotten (standard browser behaviour) so there's no link to the old session, and a new login must be provided. The old session becomes "orphaned" and (assuming you have a 'expire through inactivity' process) will be expired eventually.
If you need the browser to remember the last user even if the window was closed, then a short-but-appropriate timeout is needed - destroy the session making the cookie useless after x minutes/hours inactivity (whatever is appropriate).
I'm wondering what is happenning when a user logs in a website with or without checking a "stay logged in" checkbox.
From what I understand start_session creates a variable on the server and stores the session id on the client's browser in a cookie, destroyed when closing the said browser.
Following that reasoning, I guess that checking the "stay logged in" checkbox pushes back the expiration date by N seconds, which would be achieved by setting:
setcookie(session_name(), session_id(), time()+N);
In that case, I see no need to use cookies, at least for the logging process.
Am I right or awfully wrong? :)
There are a couple of typical ways a "stay logged in" box might be handled...
You could set the user's info in a persistent cookie, and look for that cookie.
You could create some unique ID (it better be a big one...like a GUID or a hash), store it in a persistent cookie, and let that serve as auth info.
Note that most solutions don't involve the user actually staying logged in; they just make it so that the user doesn't see another password prompt. Keeping the session alive and storing the session ID in a persistent cookie is technically possible, but for a site with a lot of users, that'd be quite a bit of extra space and load on the server.
The way I have written an option like that is to create a token and store it in the database along with the user ID. I then give that token to the browser as a cookie. Anytime a page request is done, I check to see first if the user has an active session, then if they have this token cookie. If they have a token cookie, I look into the database to see if it is valid and if so create a session with that user ID.
I'm sure this is an insecure, easily breached method, however.
I've created a login system using PHP sessions.
Here's how it works:
1.) when the user logs in (with the valid login info):
Their info (username and password) are stored into a session, along with a few other bits of info:
The Expire time: This is just 5mins added onto the current time (so if the user login is at 22:30 the expire time would be 22:35).
2.) On every page view of the user being logged in:
The session is checked to see if exists. If it doesn't, the user is redirected to the login page. If the session does exist, it then checks the expire time and compares it with the current time. If the expire time is more then the current time (the user has been inactive for 5+ mins) then their user details (in the session) are checked (compared to ones in database) and the Expiretime session is updated, but if the expire time is less then the current time, It wont check any details, updates the expire time session and will allow the user to carry on. Ive done that to prevent constant querying on the DB to save bandwidth.
So basically, once the user has successfully logged on, their username and password wont be checked on the DB again until they either become inactive (stay on one page) for 5+ mins or if they log out.
FORGOT to mention something guys:
The expire time session is actually called expire_time_unique_characters ($_SESSION['expire_time_'.$unique_nu]) which means the evil person will also have to find the $unique_nu when faking the session...
I just have this feeling that its not very secure.
Also, the project this is for is open source (people can see the source code) so that poses an even higher risk here...
can you guys give me some feedback?
Thanks
Storing user's ID in session is more than enough.
Still, you should implement some kind of protection against session fixation/hijacking.
$_SESSION is relatively secure, provided it's used right. For instance, if you keep the session files below the web root, they cannot be accessed except by someone with direct access to the server filesystem itself. For this reason, you still want to keep the password encrypted, but the username in plain text is perfectly fine.
Keep the session ID in a cookie rather than using the query string method, otherwise anyone copying the URL will inadvertently share their session and bypass login.
That should about do it. Obviously if someone is hacking the user's network and obtains the cookie data then they can use it to pretend to be the user, but there's almost nothing you can do about that. You can make it harder (require the User Agent string to be the same, for instance), but ultimately there's not much you can do if the user's network is compromised. It's not your responsibility to protect their network anyway, only their data on your server.
i have a user login system which works off of sessions such that when the user logs in a session variable of user is populated with his/her username, then each page she loads checks this session, if it is not populated then the page is redirected to the login page. apon logout the session is destroyed.
But this still allows a user to open 2 different browsers at the same time and login. I want to stop this, such that if a user logs in and then trys to login using a different browser or pc, they get an error saying the user is already logged in.
So my first thought was to use a data base write, but then how do i know to unset that value if the browser is closed?
all my pages are php, and i use ajax and php scripts to update dynamic content.
So whats the best way to go about this?
they get an error saying the user is already logged in.
That's wrong approach, causing terrible user's experience.
Make it opposite: let that latter in, but make previous one logged out.
You only need to store current session ID in the user's table. If it doesn't match - ask for login.
If you find in DB that user is already logged in simply ask if he/she wants to go on and overwrite old session info. Another way may be adding a time-ticket to your database information (e.g. inserting time) and check how long is elapsed since inserted.
Regards
If I have understood your question properly, I think you can make use of cookie. Once user is logged in, you can create a cookie and set an expiry to browser session time. Before fetching data from DB, you need to check for cookie presence.
I would make another session variable that checks the browser type, if it is different call a view method to output what you said
I'm using login function in my site with session.
This session of mine gets expired after a few minutes irrespective of whether the user has logged out or not.
Now what I want is that the session should only get expired when a user logs out. If a user doesn't log out his account and then comes back after 2-3 days, even then he should appear logged in.
I have found some examples where they have increased the time for a session to expire but I want that it should only expire on the log out event by the user irrespective of the time he took to log out.
How can I do that?
In particular, is this the right way to do so?
session_cache_expire(0);
session_start();
A solution that is often used, in this situation, is to:
have a not-too-long session duration: it will expire if the user is not active (that's just the way it works -- and that's better for your server if you have lots of users)
when user logs in, you set a cookie that contains what is needed for him to be recognized
if he comes back on the site (with the cookie, and without having an active session), you use the informations contained in that cookie to auto-log him in, re-creating the session at the same time.
This way:
you don't have thousands of sessions "active" with no good reason
you keep the standard way sessions work
And you have the advantage of "never being logged out", at least from the user's point of view.
Also note that with "normal" sessions, the cookie containing the session id will be deleted when the user closes his browser -- so, he will be disconnected, no matter how long the session's lifetime is.
With the solution I propose, you are the one who sets up how long the cookie should remain on the user's computer ;-)
It means, though, that when a user manually logs-out, you have to delete both his session and the cookie, of course -- so he's not immediatly re-auto-logged-in.
Of course, you have to be careful about what you set in the cookie: a cookie is not quite secure, so don't store a password in it, for instance ;-)
Actually, this way of doing things is how the "remember me" feature often works; except, here, your users will not have to check a checkbox to activate "remember me" ;-)
If you don't have the time to develop that kind of stuff, a pretty quick and dirty way is to use some Ajax request on all your pages, that will just "ping" a PHP page on the server -- this will keep the session active (but it's not quite a good way of doing things: you'll still have LOTS of sessions on the server, you'll have lots of useless requests... and it will only work as long as the user doesn't close his browser).
You can't do that with the PHP internal session handling alone. PHP will always send out the session id in a session-cookie which will expire when the user closes his browser. To achieve some sort of auto-login you'll need some accompanying code that sets a longer-lasting cookie on the user's browser and handles the recognition of these cookies and the mapping between the cookies value and the respective user account.
Please note that this greatly affects security issues so you'll have to take care of a lot of things. Please read the following on how a possible auto-login feature could be working:
Persistent Login Cookie Best Practice
Improved Persistent Login Cookie Best Practice
Do you remove your cookies while testing? Are cookies enabled? Do you destory the session somewhere in your code?
Also, see my answer to another post: Quick question about sessions in PHP which explains how to stay signed in. Just don't do a cronjob/sheduled task if you want the user to stay logged in forever.