persistent login –“remember me” feature

  1. FACTS:
  • when a machine is reboot, the session will lost, but the token won’t because the token is stored in the cookies
  • a session is in the memory

If you DO decide to implement persistent login cookies, this is how you do it:

  1. First, follow Charles Miller’s ‘Best Practices’ article Do not get tempted to follow the ‘Improved’ Best Practices linked at the end of his article. Sadly, the ‘improvements’ to the scheme are easily thwarted (all an attacker has to do when stealing the ‘improved’ cookie is remember to delete the old one. This will require the legitimate user to re-login, creating a new series identifier and leaving the stolen one valid).
  2. And DO NOT STORE THE PERSISTENT LOGIN COOKIE (TOKEN) IN YOUR DATABASE, ONLY A HASH OF IT! The login token is Password Equivalent, so if an attacker got his hands on your database, he/she could use the tokens to log in to any account, just as if they were cleartext login-password combinations. Therefore, use strong salted hashing (bcrypt / phpass) when storing persistent login tokens.


  • user login in, after authorization of “remember me”, the client’s cookies is updated with a username, and a token; the token->username is also stored into server’s database
  • for user’s next login, the cookie’s token will be used to match the one in the database; if it does match and is not expired, a new token will be generated and the cookie will be updated accordingly. If it does not, either report it as a theft or ignore it. Thus, automatically re-login is finished.
  • even you reboot the machine, you can still login automatically as long as the token is not expired.

Charles’ Recipe

The cookie should consist of the user’s username, followed by a separator character, followed by some large random number (128 bits seems mind-bogglingly large enough to be acceptable). The server keeps a table of number->username associations, which is looked up to verify the validity of the cookie. If the cookie supplies a random number and username that are mapped to each other in the table, the login is accepted.

At any time, a username may be mapped to several such numbers. Also, while incredibly unlikely, it does not matter if two usernames are mapped to the same random number.

A persistent cookie is good for a single login. When authentication is confirmed, the random number used to log in is invalidated and a brand new cookie assigned. Standard session-management handles the credentials for the life of the session, so the newly assigned cookie will not be checked until the next session (at which point it, too, will be invalidated after use).

The server need not make the effort of deliberately trying to avoid re-assigning random numbers that have been used before: the chance of it happening is so low that even if it did, nobody would know to make use of it.

When a user logs out through some deliberate logout function, their current cookie number is also invalidated. The user also has an option somewhere to clear all persistent logins being remembered by the system, just in case.

Periodically, the database is purged of associations older than a certain time-period (three months, perhaps: the size of the table would be far more an issue than any possibilities of collision in a 128 bit random space).

The following user functions must not be reachable through a cookie-based login, but only through the typing of a valid password:

interface cannot be instantiation

public interface Handler{
public void Hello();

import Handler;
public class OtherParser{
Handler handler;

2) just uses a declaration of the interface, which is different from instiation

public class MyHandler implements Handler{
public void Hellp(){
System.out.println(“my Handler implements”);
Handler handler = new MyHander();


In the case below, Animal is an interface. it uses an anonymous class which is actually a class; that is why it can be instantiated.

Animal animal = new Animal() {
    public void Eat(String name) {
        System.out.printf("Someone ate " + food_name);