The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

What is the best way to check a user is logged in?

Currently I have a certain way of checking a user is logged in, but recently something odd happened to the user section of the database (still is the development phase with only a few users) but the thing is im the only person with login details and I haven't touched the db in the past couple days, which is when this happened and therefore I think my site has been comprimised.

Currently all I do to check that a user is logged in is to set a heap of session variables when they login and check them before loading each page.

logged_in is set when the login
timeout is the time the login plus 10 mins
auth_level is whether they are a user or admin which allows them to get into certain areas of the site
website specifies which site they are allowed into as this site has two versions that have to be seperated.

What more can I do? I was thinking of storing something in the database and also creating a class to log everything to a database table, i.e. logins/logouts, certain page requests etc.

What do you do to check that your user is logged in and who the say they are?

If this returns a row, the user is logged in and is indeed a registered user. (Note: I do not in fact use "SELECT *", I grab only the columns I need and nothing more.) If I'm on a page that requires a higher user level (I've implemented at most 3 levels, although in another site I implemented a non-hierarchical permissions system), I check the returned user_level field with the minimum required user level (e.g. basic registered user is level 1, moderator is 4, administrator is 7 (the gaps were intentional in case I wanted to insert new levels)) to determine whether or not this user has permission to view this page. (In actuality, my user object implemented another user level, 0, for site visitors who were not logged in, aka guests.)

Most certainly not! Just like PHP's session management, I store a cookie with a session ID on the user's computer. I link this session ID to a user via a table in my database. So my query above in actuality looks more like this:

Code:

SELECT users.*
FROM sessions
LEFT JOIN users ON users.username = sessions.username
WHERE sessions.session_id='{$_COOKIE['sessid']}'
AND sessions.expired>NOW()

In effect it's just like replacing PHP's session handlers via session_set_save_handler, except that I just forego that entirely and took the extra half-step to have my sessions handled entirely by my own code, including handling all session variables (which are serialized and stored in the sessions table in the column vars in the format var1=val1&var2=val2; part of the serialization routine is URL-encoding any '&' characters that appear in values). Thus my sessions exist entirely within my user object, including session variables for visitors who have not logged in to my site.

If the user just cleans his cookie from his computer, then the user will be logged out and has to login again right? And another do you check from the database in every page load or you just check it from the cookie?

I run a commercial product that requires users to log in. The product uses PHP's session support and the $_SESSION array.

The login page requires users to enter their ID and password. This information is verified against the user's database record (in the prov_users table). If the information is correct, I save the user's prov_users.userId in $_SESSION. If the information is incorrect, I set the userId to zero (an invalid value).

At the start of each secured PHP script (both web pages and worker scripts called from web pages), I start the session and check the userId variable. If the variable is greater than zero, the user is logged in and the script continues. If the userId is zero, the user is redirected to the login page.

@kromey, I developed a role based permission system for this application. This allows me to control what individual users can do based upon their role. It has been very handy because I can change what people can do on the fly (by changing the permission database table).

@rajug, if the user clears the session cookie from their browser, they will have to login again.

mikem

Last edited by mikemckinney; Jun 26, 2007 at 20:43.
Reason: Comment to rajug.

If the user just cleans his cookie from his computer, then the user will be logged out and has to login again right? And another do you check from the database in every page load or you just check it from the cookie?

Yes, and yes.

This is far from different from how PHP's built-in sessions work:
Mine:
User clears cookie => user is effectively logged out and must again log in
Each page load => I query the database to find active session

PHP's:
User clears cookie => user is effectively logged out and must again log in
Each page load => PHP pulls the session from the filesystem

In all honesty, there is no appreciable performance difference in my pulling sessions from the database and PHP pulling from the filesystem. One huge advantage that my method has, however, is that I'm already in the database and thus if I need more information I can pull that in the same query as I pull the session information; this is as opposed to PHP accessing the filesystem and then your script taking that information to query the database, which makes for a slight performance hit.

I'm not sure if your questions were meant to highlight perceived weaknesses/flaws in my scheme, rajug, but if so then I think you need to be aware of how PHP's sessions work because they are identical except in where the session data itself is stored.

@mikemckinney:
I've done role-based permission schemes as well, which also let me change permissions on the fly; instead of a separate permissions table, however, I use a single integer column in the user table that becomes a bitmask with various constants that I define. For example, I might have the following constants (pseudo-code):

Code:

PERM_VIEW = 1
PERM_ENTER = 2
PERM_EDIT = 4
PERM_DELETE = 8

Note how each value is a power of 2; this means they each have a single bit set, and it's always in a different place. With 32-bit integers, this allows up to 32 permissions. To then check if a user has permission for a particular action, it's quite simple:

I'm sure this isn't news to you, mikem, I'm merely presenting it for the benefit of others. My testing showed that my method is not necessarily faster than pulling a list of permissions from the database (my method did always come up faster than pulling the permissions list, but only ever by 2%-7% except for a single fluke that was almost 50% faster), but it does have the advantage of requiring less memory (I need only 4 bytes for the single integer) and, at least to me, is more readable.