tags:

views:

493

answers:

7

My web application uses sessions to store information about the user once they've logged in, and to maintain that information as they travel from page to page within the app. In this specific application, I'm storing the user_id, first_name and last_name of the person. I'd like to offer a "Keep Me Logged In" option on log in that will put a cookie on the user's machine for two weeks, that will restart their session with the same details when they return to the app. What is the best approach for doing this? I don't want to store their user_id in the cookie, as it seems like that would make it easy for a user to try and forge the identity of another user.

+1  A: 

Generate a hash, maybe with a secret only you know, then store it in your DB so it can be associated with the user. Should work quite well.

Jani Hartikainen
Would this be a unique identifier that is created when the user is created, or would it change every time the user generates a new "Keep Me Logged In" cookie?
Matthew
Tim Jansson's answer describes a good approach to producing the hash though I'd feel safer if it didn't include the password
Jani Hartikainen
+3  A: 

Use some kind of "cookie" hash, the username + md5($ip, $username, $password)? That would be my suggestion. And if(md5($_SERVER['REMOTE_ADDR'], $username, $password) = $cookiehash) ? :)

Tim Jansson
Keeping a password, or anything even related to it (such as a hash, which can be bruteforced) on the client? Not adding salt to an MD5 hash even though dictionaries that are available on the Internet? -1 for security issues with this approach.
MaxVT
+5  A: 

Usually I do something like this:

1) User logs in with 'keep me logged in'
2) Create session
3) Create a cookie called SOMETHING containing: md5(salt+username+ip+salt) and a cookie called somethingElse containing id
4) store cookie in database
5) user does stuff and leaves ----
6) user returns, check for somethingElse cookie, if it exists, get the old hash from the database for that user, check of the contents of cookie SOMETHING match with the hash from the database, which should also match with a newly calculated hash (for the ip) thus: cookieHash==databaseHash==md5(salt+username+ip+salt), if they do, goto 2, if they don't goto 1

off course you can use different cookie names etc. also you can change the content of the cookie a bit, just make sure it isn't to easily created. You can for example also create a user_salt when the user is created and also put that in the cookie.

Also you could use sha1 instead of md5 (or pretty much any algorithm)

Pim Jager
Why include the IP in the hash? Also, make sure to include timestamp information in the cookie and use this information to establish a maximum age for the cookie so that you are not creating an identity token that is good for eternity.
Scott Mitchell
Nice answer. So I am assuming when they log out, the session is destroyed, the cookie is removed, and the record in the DB is deleted?
barfoon
Yes, on logout you destroy/remove everything, that way the user won't accidentaly be logged in on return.
Pim Jager
+1  A: 

I asked one angle of this question here, and the answers will lead you to all the token-based timing-out cookie links you need.

Basically, you do not store the userId in the cookie. You store a one-time token (huge string) which the user uses to pick-up their old login session. Then to make it really secure, you ask for a password for heavy operations (like changing the password itself).

Yar
A: 

Implementing a "Keep Me Logged In" feature means you need to define exactly what that will mean to the user. In the simplest case, I would use that to mean the session has a much longer timeout: 2 days (say) instead of 2 hours. To do that, you will need your own session storage, probably in a database, so you can set custom expiry times for the session data. Then you need to make sure you set a cookie that will stick around for a few days (or longer), rather than expire when they close the browser.

I can hear you asking "why 2 days? why not 2 weeks?". This is because using a session in PHP will automatically push the expiry back. This is because a session's expiry in PHP is actually an idle timeout.

Now, having said that, I'd probably implement a harder timeout value that I store in the session itself, and out at 2 weeks or so, and add code to see that and to forcibly invalidate the session. Or at least to log them out. This will mean that the user will be asked to login periodically. Yahoo! does this.

staticsan
+1  A: 

There are two very interesting articles, I found while searching for a perfect solution for the "remember-me"-problem:

Stefan Gehrig
+1  A: 

I would recommend the approach mentioned by Stefan (i.e. follow the guidelines in Improved Persistent Login Cookie Best Practice) and also recommend that you make sure your cookies are HttpOnly cookies so they are not accessible to, potentially malicious, JavaScript.

wrumsby