2

My login system currently works as follows:

  1. Grab the user's username and password from a POST form.
  2. Check the username and salted + hashed password against the database.
  3. If authentication is successful, generate a long, random, alphanumeric string.
  4. Store this string in MySQL, as well as in a $_SESSION variable along with the username.
    • This is opposed to just putting the user's password in $_SESSION. I feel like that's leaving the door wide open for spyware to come in and steal the user's credentials.
  5. On each page that requires authentication (e.g. non-sensitive account settings, members-only areas, etc.), check the $_SESSION username and string against those stored in MySQL.
  6. If they match, go ahead and show the page. Otherwise, show a login form.(?)
  7. When the user explicitly logs out, remove the random strings from MySQL and $_SESSION.

What I'm stuck on is how to handle when the user implicitly logs out. That is, when he/she closes the browser window without hitting any "log out" button on the site. I'm pretty sure I still need to remove the random string from MySQL, so someone can't use a stolen cookie to log in afterwards. But how do I know when the user closes the browser window?

("Remember me" functionality is irrelevant for now.)

Maxpm
  • 24,113
  • 33
  • 111
  • 170
  • Your random string essentially behaves like a session. Why are you storing it in `$_SESSION` and not as a cookie? Using sessions involves file-system access, and its obtaining an exclusive lock on the session file during the handling of the request, blocking it from handling other request until the request is dispatched (or until `session_write_close()` is called) - basically making everything slower. The session id created by PHP is already pretty much the same as your random string... you'd be better of storing it directly in the cookie. – shesek Aug 18 '11 at 08:56
  • Just let the session expire. http://stackoverflow.com/questions/3068744/php-session-timeout – BlueDog Aug 18 '11 at 08:59

2 Answers2

3

How Should I Implement Login Sessions?

Authentication and session management are 2 different things, although they are closely tied together, you seem to be talking about authorization too.

If authentication is successful, generate a long, random, alphanumeric string.

Why? PHP already generates a random identifier (the session id). If you want to differentiate between authenticated/non-authenticated users and/or identify which user owns the current session, just store the username / userid in the session.

putting the user's password in a $_SESSION variable

Why would you ever want to do that - once you've authenticated the user, you never need to use the password again.

check the $_SESSION username and string against those stored in MySQL

Why? How can the session data be changed other than via your code? If you suspect that your serverside code could be tampered with then it doesn't matter what you do, the system will be insecure.

When the user explicitly logs out

...you explicitly destroy the session. That's all.

When you remove the redundancies from your proposition there is no need to clean up after an implicit logout.

BTW: there are a number of security issues you have not addressed in your proposal, notably regenerating the session id after an authentication attempt.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • +1, but I do think a better solution would be to use him random string as the session id by storing it directly in the cookie, instead of using PHP's native session handling which is problematic. See my comment to the question. – shesek Aug 18 '11 at 09:15
0

You could use an ajax call on onclose event to kill the session... never tried it but it should work:

$(window).unload( function () { 
    // ajax to kill the session 
} );
Catalin
  • 858
  • 5
  • 16
  • I've never used Ajax before, and I'd like to avoid adding more layers to the site. – Maxpm Aug 18 '11 at 08:59
  • You could simply use `new Image().src='remove-session.php'` to send a request to the server. But its not much different than doing an `$.get('remove-session.php')`... Basically, just send a request to the server somehow and remove the session when processing the request. – shesek Aug 18 '11 at 11:04
  • Also, make sure to either add some delay or make the request synchronous if you're using AJAX. otherwise, the browser might stop the request before the server is getting it. You can also add `ignore_user_abort(TRUE)` so the server will keep processing the request even if the browser closes the connection - but it won't help in cases the browser close the connection before it fully sent the request. – shesek Aug 18 '11 at 11:06