09 February 2016 — Comments
I'm sure you are familiar with those "remember me" checkboxes in login forms. They are a common way to allow a user to keep his/her session in a web application for an extended period of time when he is in a trusted computer.
One could think that it is a small and easy-to-implement feature, but it has indeed a lot of considerations.
I wasn't able to properly implement it in the first projects I worked in, and I'm trying to explain everything I've learned about it in the last years.
In this article I'm not going to show you how to implement a persistent login in one or another programming language, but what are the good practices that should be followed when you implement it in the way you want.
The first thing that one could try is to extend the lifetime of the system that persists the session and identifies the user between requests (usually a cookie).
The problem is that many systems doesn't allow to do that in an isolated way, you are forced to extend the lifetime of all sessions. Also, it is not always easy to change the session lifetime dynamically.
So it's not a good idea, because the user could be accessing your app from a public computer, and his session could be stolen if he forgets to logout.
Because of this, the best way to do it is to have another element (another cookie) that keeps the persistent session and is used to transparently regenerate the regular session when it expires.
When a user logs in and he has checked the "remember me" field, you will create a cookie with an extended lifetime (for example, 2 weeks).
That cookie will contain a unique token that will identify a user. It should be backed in the database by creating a table that relates the token with a user. It could contain other metadata too, like the client's IP address or a flag that says if the session is still valid.
In consecutive requests, your system will keep checking if an authenticated user exists, but if not, instead of redirecting to a login or returning a 403 status, it should check for the persistent login cookie first.
When that cookie exists, you will find the user it belongs to, and authenticate him. Then, you will invalidate the cookie and the session in the database, and generate a new one that will expire in the same date as the previous one. Finally, the new token should be returned in a new persistent login cookie that will replace the previous one by having the same name.
When the user manually logs out, the persistent login cookie should be dropped too.
Now you have a basic idea on how to implement it, but there are some security considerations to take into account in order to avoid problems in the future.
The first thing that we have to assume is that persistent sessions have their risks. There is no way to implement a completely secure persistent login, but following this instructions the system will be reasonably secure.
HttpOnly, so that they cannot be read from the browser.
Of course, if your system manages critical data, you shouldn't implement persistent login at all. I don't think you have seen it at any bank application.
In any other case, this should be a good way to go.