5

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..

2
  • 2
    Basically, there's no point in having a logout button if you're always automatically signed in. If you're using the button so that people can't log in as you once you're done, then you don't want auto login enabled when you click it. Otherwise, just close the browser to 'log out'.
    – Rob
    Dec 18, 2011 at 22:28
  • "Remember Me" is for when you close the browser without clicking on "Log Out". If it was not checked, the cookie only lasts for that browser session.
    – Izkata
    Dec 19, 2011 at 3:55

3 Answers 3

5

Let's clarify a few things first:

  1. 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.

  2. 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:

enter image description here

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:

  1. A user id,
  2. The token,
  3. An expiration date

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 the secure parameter to true:

Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client. When set to TRUE, the cookie will only be set if a secure connection exists. On the server-side, it's on the programmer to send this kind of cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).

1 I don't delete expired tokens for a variety of reasons.

5
  • Very nice answer!I understand the workflow, I just thought that "autologin" was...well, I don't know what I was thinking, actually...anyway, it's much more clear now, thank you! As for how I do it: 1) generate 16 chars random string (if available, with random.org) and hash it; 2) encode user_id and prepend to the random string; 3) save whole string to cookie; 4) save hashed random string of point 1) into DB; 5) Upon retrieval, split the cookie and get user_id and the random string; 6) fetch db autologin_code field where userid = user_id, hash random string and see if they match Dec 18, 2011 at 23:28
  • Oh, and I also have an expiration date saved in the DB, yes, just in case. Nice tip about checking ath each request; I actually do something similar on controller's constructor, but so far I'm separating session login check and autologin (first I see the former, when negative, see the latter. I might rework this, it seems) Dec 18, 2011 at 23:31
  • As for session, the framework I use doesn't natively use php sessions but cookies on steroid. But it menages them like it were session, I mean, it provides a sess_destroy() method which destroys the cookies used as session while keeping any regular cookie, and a delete_cookie() which does the opposite. Dec 18, 2011 at 23:33
  • That's what I intended to do, yes. Thank you for your time, @Yanis, I see things clearer now, wish I could +1 more! Cheers! Dec 18, 2011 at 23:40
  • 1
    @DamienPirsy Nice. If (when) you have working code, make sure to post it for peer review at Code Review Stack Exchange, we can go into a lot more detail on implementation specifics there. What CI does is setting a user defined (in this case framework defined) session handler, check my other answer I've linked to at point 1 to see how that works (and get some inspiration on possibly storing everything in the database)...
    – yannis
    Dec 18, 2011 at 23:40
5

I do not mean to overstep @Yannis Rizos's extensive answer, but I just want to answer a very specific item you asked about: The "Log Out" option exists precisely so that the user can indicate that they do not wish to be remembered anymore. Check any major website, and you will see that they all work this way: once I have checked the 'remember me' checkbox in the log-in screen, and for as long as I don't explicitly log out, I am remembered. Once I explicitly log out, I am not remembered anymore.

A couple of more points:

In all major web sites I know of, "remember me" of course means "remember both my user name and my password"; in other words, "please don't bother me with log-in screens".

Also, the state of the art nowadays for web sites that are generally used by people daily, such as gmail, apparently seems to be that about once a month you should forget your users anyway, meaning that they see a log-in screen and have to re-type their credentials once a month. Apparently they (i.e. the guys at gmail) have done some research on this subject and they found out that this helps users keep remembering their password, with a minimum of annoyance. (Just once a month.)

2
  • Thanks for the answer. Now I see better where I was wrong. As for your 2 points: 1) that was my itention, I only messed up with practical distinction (see my various comments); anyway, now, with autologin active ad when "sessions" are expired, there's the autologin code (if the user didn't log out) which is by default set to 14 days (I also made some researches and came up to values of the like; I've seen the 2 weeks timespan being used more frequently than the month, though) Dec 19, 2011 at 0:01
  • 1
    +1 and you are not over stepping... I though of writing something similar, but my answer was already getting too long, and it's 2am here so... Goodnight!
    – yannis
    Dec 19, 2011 at 0:10
0

Log out should Log the user out until he\she (manually) logs in again. ie: an Temporary dis-ablement of the auto logon.

In other words, delete the cookie.

Remember me should only remember the username not the password.

9
  • Ok, so what makes the autologin different from a regular session check? they're just two different methods, i.e. the session is expired but the cookie is not, so use the latter? Dec 18, 2011 at 22:28
  • Exactly, the auto-login will log you the next morning. Imaging having to keep every session open forever, just to support an auto-login feature, what a waste of memory!
    – Morons
    Dec 18, 2011 at 22:31
  • @DamienPirsy Cookie expires too, but you can set when it expires. Sessions, in theory, expire when the session ends, i.e the user closes the browser. In practice they expire some little time after the last request to the server. And to confuse you a little more, technically sessions are cookies...
    – yannis
    Dec 18, 2011 at 22:34
  • @Morons Not a waste of memory per se, Damien refers to PHP sessions, which are essentially a cookie based persistence mechanism. "Keeping a session open" means not expiring the session specific cookie.
    – yannis
    Dec 18, 2011 at 22:35
  • @YannisRizos as for your last sentence (of your previous comment), I know that; especially when dealing with CodeIgniter, which doesn't make use of native php sessions but instead uses regular cookies. So, summing up, regular session/cookies (in CodeIgniter's case) expire after x seconds, user can choose to have them last y seconds with my library's autologin, but he doesn't have to sign out. I think I got it. I think I gave to the "autologin" a too exoteric nature Dec 18, 2011 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.