How do I keep a user logged into my site for months?

10,612

Solution 1

So you actually want like a "Remember me on this computer" option? This is actually unrelated to OpenID part. Here's a language-agnostic way how you can do it:

  • First create a DB table with at least cookie_id and user_id columns. If necessary also add a cookie_ttl and ip_lock. The column names speaks for itself I guess.

  • On first-time login (if necessary only with the "Remember me" option checked), generate a long, unique, hard-to-guess key (which is in no way related to the user) which represents the cookie_id and store this in the DB along with the user_id. Store the cookie_id as cookie value of a cookie with known cookie name, e.g. remember. Give the cookie a long lifetime, e.g. one year.

  • On every request, check if the user is logged in. If not, then check the cookie value cookie_id associated with the cookie name remember. If it is there and it is valid according the DB, then automagically login the user associated with the user_id and postpone the cookie age again and if any, also the cookie_ttl in DB.

In Java/JSP/Servlet terms, make use of HttpServletResponse#addCookie() to add a cookie and HttpServletRequest#getCookies() to get cookies. You can do all the first-time checking in a Filter which listens on the desired recources, e.g. /* or maybe a bit more restricted.

With regard to sessions, you don't need it here. It has a shorter lifetime than you need. Only use it to put the logged-in user or the "found" user when it has a valid remember cookie. This way the Filter can just check its presence in the session and then don't need to check the cookies everytime.

It's after all fairly straight forward. Good luck.

See also:

Solution 2

Well, the original reason I chose OpenID was so someone else could handle as much of the implementation and security of authentication for me.

After looking into OpenID more, it appears there is something called an "Immediate Request" (http://openid.net/specs/openid-authentication-2_0.html#anchor28).

When requesting authentication, the Relying Party MAY request that the OP not interact with the end user. In this case the OP MUST respond immediately with either an assertion that authentication is successful, or a response indicating that the request cannot be completed without further user interaction.

Because of this I think I could just store the user's openID url in the cookie, and use an immediate request to see if the user is authenticated or not. This way I don't have to do anything with my database, or implement any logic for preventing session hijacking of the long-lived cookie.

This method of doing it seems to be the way OpenID suggests to do it with their Relying Party Best Practices document.

Share:
10,612

Related videos on Youtube

Kyle
Author by

Kyle

Updated on April 15, 2022

Comments

  • Kyle
    Kyle about 2 years

    I'm using OpenID. How do I make it so that the user stays logged in for a long time even after closing the browser window?

    How do I store and get access to the user's User object?

    Basically, I guess I just don't really understand how sessions work in Java.

  • Kyle
    Kyle about 14 years
    Thanks BalusC, do you know of any automagic way all of this could be implemented for me? Or do most sites actually make the database table and logic themselves? I just figured that this is such a common thing to do that it would be built into a library or the language or something.
  • BalusC
    BalusC about 14 years
    Sorry, no one comes to mind. But this is all truly doable yourself. If you somehow stucks and/or have questions, just Ask Question here :)
  • sfussenegger
    sfussenegger about 14 years
    -1 This approach is a considerable security risk. It's easy to sniff or otherwise steal cookies and reuse them from anywhere on the web. It's basically session hijacking on steroids.
  • BalusC
    BalusC about 14 years
    @sfussenegger: How is it different from the normal Servlet HttpSession (jsessionid), PHP $_SESSION (phpsessionid) and any other session construcs used by other weblanguages/frameworks? I just explicitly said "generate a long, unique, hard-to-guess key (which is in no way related to the user)". It's easier to hijack the code used to encrypt the session data and abuse it (especially if it's distributed and/or open source), than to guess/hijack a completely random session key and abuse it. That pissed-like -1 from you makes no utter sense, but if that makes you feel better, be my guest :)
  • BalusC
    BalusC about 14 years
    @sfussenegger: I see that you're the other answerer here. How is your own answer more safe? You're basically storing all the sensitive information in a cookie instead of in a DB in server side! Encrypted or not, it's unsafe and may affect all users whenever the code logic to encrypt it is hijacked/revealed. Also you may have missed the whole point of cookie_ttl and ip_lock I mentioned in my answer.
  • Kyle
    Kyle about 14 years
    Hi BalusC, I was wondering if you could look over my answer to this question: stackoverflow.com/questions/2185951/…, and let me know if you see any flaws in it?
  • sfussenegger
    sfussenegger about 14 years
    0 - I've overlooked cookie_ttl and ip_lock the last time, sorry :) I wouldn't say they speak for themselves though. It's important to check these two every time a user is authenticated with a cookie_id (which you didn't say explicitly). However, breaking a common symmetrical encryption algorithm like AES or Tripple-DES as you said isn't easier than breaking your random key generator. Additionally, it's easier to identify illegal values as they will result in gibberish after decryption. An illegal cookie_id might simply be obsolete.
  • BalusC
    BalusC about 14 years
    That's certainly an interesting alternative en more suited to the OpenID ideology. I myself however haven't used OpenID in my webapps yet, but after reading one and other I'd say, go for it as described in the document you linked.
  • sfussenegger
    sfussenegger about 14 years
    that's probably the best answer
  • artaxerxe
    artaxerxe over 12 years
    @BalusC I'm a relatively new in webapp environment. You said: "On every request, check if the user is logged in". How is this achieved best in a JSP/Servlets webapp?
  • Rajat Gupta
    Rajat Gupta about 12 years
    @BalusC: Is there any harm in storing userId(not the password) along with the UUID in the cookie ? I am seeing some use of that if saved in cookie.
  • Ommadawn
    Ommadawn over 6 years
    @BalusC: I think I'm the one that doesn't understand what does "cookie_ttl" means... Could you explain a little bit?
  • BalusC
    BalusC over 6 years