I've (so far) been handling user sessions with client-side cookies and database entries.
When the user logs in, I generate a guid and place it in a cookie on the client's computer. Then I create an entry in a 'sessions' MySQL table, and add there the guid, ip address, the username, privileges, etc. Then when the user accesses the page, I check if there's a session cookie. if so, I check the database for the guid in the cookie and make sure the ip address matches. If it does then the user is logged in with the rest of the information in the db table. If something is wrong (bad ip address, expired session, etc) I remove the database entry and remove the guid cookie.
I've never used the $_SESSION global before.
Is my way good practice or do I need to re-think how I'm handling this?
HTTP session management represents the core of web security. All possible mitigation measures SHOULD be adopted to ensure sessions are secured. Developers should also enable/use applicable security measures.
There are three primary threats to the security of a session management system in the context of a web application: Man-in-the-Middle: If you can intercept unencrypted HTTP traffic between a user and the webserver, you can steal any user's session identifier.
Anyone who can steal a user's session identifier can impersonate the user who legitimately possesses it. Let's make sure that doesn't happen. There are three primary threats to the security of a session management system in the context of a web application:
Make sure you use HTTPS and configure PHP for optimal security. Paragon Initiative Enterprises is a Florida-based company that provides software consulting, application development, code auditing, and security engineering services. We specialize in PHP Security and applied cryptography.
It sounds like you've got the basics covered. However, if you're doing that all manually, then you are effectively just implementing your own $_SESSION
, and not taking advantage of the fact that it can already do all that for you.
If you want to use a database to handle a session, you can override the default session handling with your own. Take a look at session_set_save_handler(). I do this in my apps.
class SessionHandler
{
public function open($save_path, $session_name)
{
$this->sessionName = $session_name;
return(true);
}
public function close() {
//stuff
}
public function read($id) {
$expiretime = date("Y-m-d H:i:s",time() - $this->maxLifeTime);
$sql = "SELECT * FROM sessions where sessionid='".$this->db->escapeData($id)."' AND lastupdated>='".$expiretime."' LIMIT 1";
$result = $this->db->query($sql);
//etc.
}
//etc.
public function setAsSessionHandler()
{
session_set_save_handler(
array($this,'open'),
array($this,'close'),
array($this,'read'),
array($this,'write'),
array($this,'destroy'),
array($this,'gc')
);
}
}
$sessionHandler = new SessionHandler();
$sessionHandler->setAsSessionHandler();
You can have all the functionality you just described that you've implemented yourself by using this, but still have the power of $_SESSION to do it for you.
For instance, if you wanted to add an IP check to see if the session is still valid before you start it, you can add that as part of the "open" function. If you wanted to write the session data to ten different databases (not that you would), you could accomplish this in the 'write' function.
Those functions are all used based on how you use $_SESSION, and by putting them into a simple class, you can manage how it works very effectively.
You'll see that the session id is a parameter passed to the read/write/destroy functions, and you'll still manage this the same way using your GUID generation routine. However, you could stick the guid generation and checks into this session manager class and simply have the open() function do them. Centralized, no muss, no fuss.
The way you're doing it now is good if you somehow need to link the current user to other database information.
Using sessions is the preferred way to do it for simplicity. I suggest you read a bit about it on www.php.net/sessions and make up your mind from that. It's very easy to use, but it is less flexible than using a database table. You can still set all the values you need, but you'd then have to fetch them and insert them into the query whenever you need to use them for database operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With