views:

1219

answers:

3

hello,

I use a simple login system based on SESSION vars. Once the user logs in, a session var is set that tells my script the user is to be accepted in. I don't use any custom clientside cookie var.

I would like to offer the option on the login screen that says "keep me loggued in the whole day". How does one do that in a secure way?

A: 

One option could be to set up a MySQL table that saves session variables and associates them with IP addresses and an expiration, but I'm not sure of all the details on how that would be implemented.

The simplest (though not recommended) way to do what you're looking for would be to set a $_COOKIE with the username and password on the computer, which your site will then check for when the user signs on.

For added security, you would be better served to save just one cookie as a salted MD5 hash of the user's data in order to provide a potential hacker less information about the user's account data. The duration can be set when you set the cookie; php.net has reasonably complete documentation on how to do that.

Kaji
Please don't put the user's password in a cookie
Simon
Agreed, hence the hashing suggestion I followed it up with. I'd strongly recommend against the same kind of hash you're presumably using to store the user's password in the first place, as that'd be almost as bad. Base it on different unique data or at the very least use a different salt for it.
Kaji
A: 

When you say "keep me logged in the whole day", I'm assuming you mean on that specific machine only, correct? You could use a mysql table to remember 'time of login', or a timestamp of when that login will no longer be valid if they choose to keep themselves logged in all day. Then add some script to the beginning of your code that retrieves the id of that user from the session vars. Compare the current timestamp of that user against the stored 'last valid ts' and if it's past that time, you know they should be logged out, at which point you wipe the session and force the user to log in again. This method means they won't actually be logged out until they try and do something past that point, but it will seem like it to them. Also, rather than using a mysql DB you could also store that last valid TS in a session variable as well.

So for example when the user first logs in with "keep me logged in all day selected":

$_SESSION['log_me_out_at'] = strtotime(date("Y-m-d ")."23:59:59");

Then each time a page is accessed in your system:

if( $_SESSION['log_me_out_at'] < time() ){
  unset($_SESSION['user_is_accepted_in']);
}
eCaroth
Forgot to mention that by doing this with session vars you're limiting the access to that specific machine, and since the session variables aren't accessible from the client side in any way you have no worry about this data being modified outside your control.
eCaroth
the problem with your logic is that the session vars are not to be configured to last for a whole day! So they will expire before the actual 24H - thus forcing the user to log in again.
pixeline
Then set a cookie on the users machine with their uname with the expiration being the end of that day. Store a record in a mysql table with their uname and IP address they logged in at, and if they access the app from that IP and the timestamp is still valid, let em in else force them to log in again.
eCaroth
@pixeline: the problem with your logic is that the timeout of the cookie/session is configurable.
Dereleased
uh, i meant: i don't want to change the server session expiry time for the whole server, only for my application. But your answer looks promising. i'm looking at it.
pixeline
+4  A: 

First: Configure the session.cookie_lifetime directive, either in php.ini, configuration files, or via session_set_cookie_params().

Next, store the username and the hash value of the password in the session, and validate that login on every page. As long as it's still valid, they get to stay logged in.

The session cookie's natural expiration should generally keep things tidy, as you won't have anyone getting logged out in the middle of their session (if the stars aligned for it, of course) if they keep it active. Failing that, though, I'd consider eCartoth's solution a close second, as you could just add a second line to the if statement:

if (my_validate_user_function($_SESSION['username'],$_SESSION['passhash']) 
    && $_SESSION['deathstamp'] > time()
) {
    // user is logged in again, oh boy!
}
else {
    // send in the death robots
    header('Location: /login.php',true,302);
}

EDIT: One thing you might want to consider is session fixation and/or session hijacking. In order to prevent that, I'd recommend one (or both) of two solutions:

  1. store the user's IP address in the session
  2. use session_regenerate_id() after every successful login attempt.
Dereleased
Using SESSIONS is the only way to begin a good security system, +1
TravisO
can you explicitate your last edit: why storing the user's ip address and regenerate the session id?
pixeline
PHP Accepts multiple mechanisms to specify the session ID (e.g. Query String), which allows someone to set up a predetermined session ID, send it via url to an unsuspecting victim, and once they've logged in the malicious user may use that same session ID to fake the legitimate user's login credentials which are stored in the session. By storing the IP and/or regenerating the session ID on every request, the malicious user's "fixated" session ID is, in effect, worthless. Read this for more information: http://en.wikipedia.org/wiki/Session_fixation
Dereleased