I'm going to try to coalesce everything that's been said in the comments into one answer. As such, please show other helpful users some love by upvoting their answers / comments! I'm also going to give a brief overview of how sessions work, to make the answer useful to a wider audience.
When a user logs into a website, a session is created to identify them. Sessions are handled in PHP by creating a session ID, then associating that ID with a variable store on the server side, which is accessed in PHP scripts using the $_SESSION
superglobal. The session ID is stored in a cookie on the client-side, and identifies their session.
In order to remain secure, the session ID must be unique, random and secret. If an attacker guesses your session ID, they can create a cookie on their own computer using that same ID, and take over your session. They'd be logged in as you! This is obviously bad, so PHP uses a strong random number generator to create those session IDs. In order to make things more secure, you can enable SSL site-wide and inform the browser to only ever send the cookie over SSL, using the HTTPS-only flag. This might be overkill for your site, though.
In order to prevent leaked session IDs from being useful forever, or bad guys sneaking into your room after you've gone out to the shop, sessions use timeouts. It is best to have them expire after a reasonably short time - between 10 and 60 minutes depending on your security requirements. You can reset the timeout every time you view the page, so an active user doesn't get logged out.
In order to allow the user to be remembered (i.e. the "remember me" checkbox), you need to provide a cookie that works as an authentication token. Keep in mind that this token is, for all intents and purposes, the same as having your password. This means that if the bad guy steals the cookie, they can log into your account. In order to make this option safe, we can use a one-time token. These tokens should be single-use, random, long and secret. Treat them as if they were passwords!
Here's how to implement them:
- Generate a random token. Use
/dev/urandom
if you can, otherwise you need several hundred values from mt_rand
to get something "random" enough, then hash the resulting string with SHA1 to produce the token.
- Use a strong password hashing algorithm (e.g. PBKDF2 or bcrypt) to create a hash of the token. Do not use SHA1 or MD5 for this purpose - they are NOT designed for hashing passwords!
- Insert the hash into a database table, along with the ID of the user it belongs to and the date it was created.
- Set the token in a cookie on the user's side.
- When the user visits the site, is not logged in, and a login token cookie is detected, hash the token value from the cookie using the same algorithm you used in step 2, and look it up in the database. If it matches an entry, log the user in as that ID.
- Delete the entry from the database and issue a new one (back to step 1).
You should also run a script that looks for very old session tokens (e.g. 3 months or more) and delete them. This will require the user to log in again when they come back after a long period of inactivity.
For a longer explanation of this, and many more important bits of information about secure web form login systems, read The Definitive Guide to Forms-Based Website Authentication and take a look at the OWASP project.