I'm developing an authentication library (*) for a website and I realized that maybe I'm not completely understanding what an "autologin" feature is, and how to develop it.
While gathering infos and studying other code I came across a couple of libraries which implement the option to login the user without having to sign in (these libraries are Tank Auth and Ion Auth, built for the PHP framework CodeIgniter); basically they work on creating a cookie which, in case the user is not logged (session datas are not set) but this cookie is found, it allows them to login nonetheless.
Ok, so far it's clear. What I don't understand, though, is why both library delete the autologin cookie when the user logs out. I mean: I log in, I check the "remember me" option (**), I do what I need to do in my admin panel, then I log out; if the autologin cookie is deleted, next time I'll have to log in again by filling the form, ignoring the option I flagged. What's its purpose then? I thought this "autologin" would be an extendend login which allowed me to avoid having to fill in the sign in form again.
So I went on and developed my autologin feature, but of course I bumped into the problem of not being able to logout at all, as I'm not deleting it. So I log out, redirect to the home page, then go to the admin panel and the system logs me in…well, it works as expected, but I'm not sure if this is how it's meant to be…How should this be done correctly?
Can someone explain to me how this actually should work? I'm getting a bit confused
P.S. Don't know if this is the right place to ask it, or if SO is a better fit; I'm sorry if I posted on the wrong SE site.
(*) Please don't tell me "don't reinvent the wheel" or any variant of it; I'm doing this to learn and I'm planning to make it an open source project for the public amusement, so I volutarily do want to reinvent the wheel, at the cost of making it oval.
(**) I think I guessed the difference between the "remember me" option and the "autologin" feature; so far, I didn't consider the first one ( 1-because many browsers ask you to do that nonetheless; 2-because I don't know how to do it right, i.e. how to have the login fields automatically filled without this posing the security threat of having the password stored in clear text inside a cookie), but please tell me if I misunderstood this also..
Best Answer
Let's clarify a few things first:
PHP sessions, in their default form are cookie based, I have an overview of how they work in another answer. But since they are cookie based, to me that says that if you are going to base your authentication and authorization workflow around cookies, go with normal cookies for everything - and just use sessions for what they are good for: session data persistence.
The circular login pattern you noticed is exactly why you should delete cookies on logout. Also, as @Morons writes, when a user clicks log out, expects to actually log out. It doesn't cancel out the auto-login feature, but one should be able to log out at any time.
Now, my auto login-approach goes something like this:
Which of course is pretty basic, but what is really important is the whole "cookie is valid" check. When a user successfully logins with the "remember me" option checked, I generate an auto-login token: A sensibly unique random string, most probably a salted hash.
That's the only thing I store in the cookie, nothing else nothing more. There is no actual need to store anything that could possibly identify an individual user in a cookie, you should avoid storing stuff like usernames and emails (even hashed). In my database, I have a simple
token
table that basically stores:And my check involves just checking against this table. The expiration date may seem like an overkill, as you can expire the cookie whenever you want but: You should treat everything that comes along with the cookie as user input, unsafe and easily faked. That includes it's expiration. And of course at log out I don't bother killing the cookie, I just set a
NOW()
as the expiration date. Easy as pie, and I keep most elements of the check server-side, where it feels a little bit more safe.In a recent project, I went a step further and added the check at every page request instead of storing something in a session to indicate an authorized session. Some may argue that the call to the database will lead to performance issues, but my 'token' table has grown to about 10 million tokens1 and still I haven't noticed any actual issue. Keep in mind that sessions involve file system access, that's almost never faster than a simple
select
.Of course, any cookie that stores anything related to authentication and authorization should be encrypted. And I'd recommend you always enforce secure cookies, with
setcookie()
is as easy as setting thesecure
parameter to true:1 I don't delete expired tokens for a variety of reasons.