0

I am currently implementing "auto login" mechanism in JSF. A filter is implemented to intercept each request, and check if a user is logged in by reading cookies.

When a user first logs in, in the managed bean, the cookie is saved in this way:

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
Cookie cookie = new Cookie("myCookieRef", value);
cookie.setPath("/");
cookie.setMaxAge(3600);
response.addCookie(cookie);

Later if the user performs a redirection, in the filter, I use the following code to retrieve the cookie:

Cookie[] cookies = request.getCookies();
if (cookies != null) 
{
   for (Cookie cookie : cookies)
   {
       if (name.equals("myCookieRef")) 
       {
          return cookie;
       }
    }
}

request is the HttpServletRequest object.

The problem is the returned cookie always has a -1 maxAge and null value.

I don't know if I miss anything when adding the cookie, or should I specify some additional attributes for the cookie?

Many thanks.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
qiuzmjq
  • 137
  • 2
  • 12

1 Answers1

3

Client doesn't send cookie attributes other than name and value back to server.

See also RFC6265 section 4.2.2 (emphasis mine).

4.2.2. Semantics

Each cookie-pair represents a cookie stored by the user agent. The cookie-pair contains the cookie-name and cookie-value the user agent received in the Set-Cookie header.

Notice that the cookie attributes are not returned. In particular, the server cannot determine from the Cookie header alone when a cookie will expire, for which hosts the cookie is valid, for which paths the cookie is valid, or whether the cookie was set with the Secure or HttpOnly attributes.

Max age is behaving as specified. Moreover, if it has expired in client side, then the entire cookie just won't be sent from client to server. In server side, you usually just prolong the cookie's lifetime on every "auto-login" by simply setting a new cookie with same name/value and check in requests without logged-in user if the cookie is present or not, not if it is expired or not.

If the max age value is really important to you for other reasons, just store it in your side in some database along with the unique cookie identifier (the cookie value).

As to the null value, this indicates a problem in your own code not in the cookie. This problem is not visible in the information provided so far, but I'm sure if you check/debug it once again, you'll discover a simple mistake.

As to the concrete functional requirement of "auto login", this might be a helpful read: How to implement "Stay Logged In" when user login in to the web application.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the answer. I have another question: I first sign in with checking "remember me", then I sign out, before signing out, I retrieve the cookie, and set the maxAge to 0 in HttpServletResponse. Then I sign in again without checking "remember me", this time, in the filter, I still can still retrieve the same cookie, which is created during the first time sign-in, I don't know why the cookie is still present. Beside, regarding the cookie name, should it always be the same one? Even if different users log-in? If a user logs in without checking "remember me", should a cookie be created? – qiuzmjq Mar 29 '16 at 07:01
  • Apparently you've multiple cookies on different paths. A common starter's mistake is that cookie path is never explicitly set and therefore defaults to currently opened folder in URL. You should explicitly set the cookie path to a common parent of all those folders you'd like to have this cookie available. If this is the webapp's root folder, set `"/"`. See also a.o. http://stackoverflow.com/a/28177426 – BalusC Mar 29 '16 at 07:33
  • I have set the path to "/". It is strange to me that the second time log-in, in the filter, the cookie is still present, even if I have set the maxAge to 0 in the HttpServletResponse induring the first time log-out. – qiuzmjq Mar 29 '16 at 08:04
  • Clear all cookies in webbrowser before continuing testing, or spawn an incognito window. – BalusC Mar 29 '16 at 08:07
  • That might be my mistake, I didn't clear the cookies....I will try it later. Thanks. I have another question, here is a scenario I have tested: A user directly closes the browser without clicking log-out first (log-in without "remember me"), then the user loads the page again, in the filter, the cookie is present in the request (normal, because cookie maxAge is not changed to 0 when closing the browser), and the user is automatically logged-in, which is not what I want. – qiuzmjq Mar 29 '16 at 08:49
  • Is there a way to solve this? what is the relation between cookie and session? I use session scope. As what I know, session won't get destroyed when the browser is closed, it is up to the server's decision. Therefore, I can't use @PreDestroy. I can't use Jquery.unload neither, because a user can also close the tab only, not the browser. Also in my application, several tabs can be opened at the same time...Any suggestions? Sorry for this silly question, this is my first time to work on cookie/log-in/log-out stuff... – qiuzmjq Mar 29 '16 at 08:49
  • Ask questions in Questions not in comments. Press [Ask Question] button to ask a new Question. – BalusC Mar 29 '16 at 08:49