I thought sessions would be a solution but sessions expire.
Another option, is to store a unique token in a cookie and then match with a stored token in the database, to retrieve logged in user data. This is the most secure solution but the problem i see with this is, there are many times in my code where the logged in username and userid is needed but querying all the time would use up resources unnecessary(is this true?)
What is the solution?
If it is not needed on the client, make sure it does not end up there.
Since userId’s are specific to a logged in user and not a specific computer, a cookie does not seem like the way to go.
Basic authentication in PHP is usually done with sessions, so you could just as well add the userId to the session.
If the session times are too short, increase the session time.
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/urandomif you can, otherwise you need several hundred values from
mt_randto 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.
I store such information in a database and on startup create a user object in my global object-registry. The user object holds information like user-name or e-mail and allows for changes of those infos. The login-status itself is stored in the session and also in a cookie.