Cookie getMaxAge - java

I can't retrieve cookie maxage it always returns -1
Creating cookie:
Cookie securityCookie = new Cookie("sec", "somevalue");
securityCookie.setMaxAge(EXPIRATION_TIME);
Retrieve cookie:
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for(int i=0; i<cookies.length; i++) {
Cookie cookie = cookies[i];
if ("sec".equals(cookie.getName())){
int age = cookie.getMaxAge();
}
}
}
i am always getting age = -1
also when i check in firefox cookie expiration i see strange date.
Thx

When a browser sends a cookie back to the origin server, it doesn't include any age. So it is logical that your "retrieve" code above does not receive a max age: it is not included in the request.
When the cookie is received from the server, the browser uses the max age parameter to determine how long the cookie should be kept; the age is never communicated back to the server, an expired cookie is simply discarded. When processing a request, if you want to renew the age of the cookie, reinclude the cookie in the response.
Also see the section "Sending Cookies to the Origin Server" in the RFC.

The API says that -1 means until browser is running:
Returns the maximum age of the cookie, specified in seconds, By default, -1 indicating the cookie will persist until browser shutdown
What is the value of EXPIRATION_TIME constant?

The value may be modified by the browser.
You create a cookie and want to set a max age. The cookie is sent to the browser. The browser may reject the cookie or ignore a max age too long for its policy. This modified cookie is sent back to your application.
Check your browser settings.

Just for grins, can you retrieve the value of the cookie from the browser using javascript ?
Also, can you put a filter before your servlet/jsp so that you can check the value of the cookie after the servlet/jsp sets it ?

Related

Maxage of my cookie is reset to -1

I am trying to create a cookie and set its max age.
i am using set Comment and set Max Age method to set the same.
HttpSession browserSession = httpRequest.getSession();
Cookie cookie = new Cookie("SESSION", browserSession.getId());
cookie.setComment("test");
cookie.setMaxAge(Integer.MAX_VALUE);
httpResponse.addCookie(cookie);
but when i fetch cookies form Request and then i debug it, comment is null and max age of cookie is -1, the cookie name i am setting as SESSION.
why is this happening?
This is expected behaviour. Take into account that max-age applies to a client-side, but clients will only send to server the pair name value.
So, if you set "3600" to your cookie and add it to the response, you should see that on the cookie from the client side, but the cookie contained on the very next request will show you, probably, -1, on the server side.
See RFC6265 4.2.2 for further information.

Cookie set on the response doesn't show up in subsequent request to server until browser has made two new subsequent requests

An initial request is made to the server, and in the response a cookie is added:
response.addCookie(studyPrefsCookie);
On the web page, in the developer tools, I can see the cookie that was just set. Great. Here's a pic:
My assumption is that now that the cookie is set, every subsequent request to my web application (same domain, same servletcontext, etc), will now contain this cookie value in the cookies available from the request object. However, it appears that on the very next request, the cookie value is not there, even though by inspecting the request in the developer tools shows the cookie value as being sent. On the second subsequent request, it shows up normally. Here's what the request looks like, same each time from the browser:
I even tested this again by starting from scratch, and then making an ajax call after the the first page load, back to the server. First ajax call had all the right cookies as far as the browser was concerned, but the httpservletrequest object's cookies didn't have it. Making another identical ajax call, now the server found the cookie value. Is this expected behavior?
I'm reading the cookie the same way on the server side, with some helper methods:
Cookie[] cookies = studyCookieService.getCookiesByName(request.getCookies(), "STUDYPREFS");
if(cookies.length > 0 && studyCookieService.doesCookieContainValue(cookies[0], studyCookieService.getConsentNotCompletedCookieValueWithoutStudyId())){
//redirect
return "redirect:/" + STUDY_CONTROLLER_REQUEST_PATH;
--service methods
public Cookie[] getCookiesByName(Cookie[] cookies, String cookieName){
List<Cookie> matchingCookies = new ArrayList<Cookie>();
if (cookies != null) {
for (Cookie ck : cookies) {
if (cookieName.equals(ck.getName())) {
matchingCookies.add(ck);
}
}
}
return matchingCookies.toArray(new Cookie[matchingCookies.size()]);
}

In Java servlet, cookie.getMaxAge() always returns -1

If I set a cookie with a setMaxAge() well into the future, when I read the cookie back into memory in a subsequent request, the getMaxAge() gives me back a -1. I have checked the actual cookie via Chrome's settings, and inspector, and I can verify that the expiration date is indeed set 60 days in the future.
static public void setHttpCookie(HttpServletResponse response, String payload) {
Cookie c = new Cookie(COOKIE_NAME, payload);
c.setMaxAge(60*86400); // expire sixty days in the future
c.setPath("/"); // this cookie is good everywhere on the site
response.addCookie(c);
}
static public String checkForCookie(HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if ( cookies != null ) {
for ( Cookie c : cookies ) {
if ( COOKIE_NAME.equals(c.getName()) ) {
int maxAge = c.getMaxAge();
logger.debug("Read back cookie and it had maxAge of {}.", maxAge);
String payload = c.getValue();
return payload;
}
}
}
return null;
}
Why does c.getMaxAge() always return -1?
The browser does not send cookie attributes like path and age back. It only sends the name and the value back. If the max age is expired, then the browser won't send the cookie anyway. If the path is not covered by request URI, then the browser won't send the cookie anyway.
If you really need to determine the cookie's age after you have set the cookie, then you should remember it yourself elsewhere at the moment you've set the cookie, such as in a database table, associated with the logged-in user and cookie name, for example.
This problem is unrelated to the Java/Servlets. It's just how HTTP cookie is specified. You'd have exactly the same problem in other web programming languages. See also the following extract from Wikipedia (emphasis mine).
Cookie attributes
Besides the name–value pair, servers can also set these cookie attributes: a cookie domain, a path, expiration time or maximum age, Secure flag and HttpOnly flag. Browsers will not send cookie attributes back to the server. They will only send the cookie’s name-value pair. Cookie attributes are used by browsers to determine when to delete a cookie, block a cookie or whether to send a cookie (name-value pair) to the servers.
The best what you can possibly do is to bump the cookie's max age every time during e.g. login. You can easily achieve this by setting exactly the same cookie once more (especially exactly the same domain/path/name). It will overwrite the existing cookie. This is usually done that way on so-called "Remember me" cookies.

Sharing sub domain cookies

I have a domain 'www.foo.com' and I want to create sub domain 'test.foo.com'.
In order to combine those 2 domains to share only one cookie I set the cookie to be like that:
Cookie cookie = new Cookie("myCookie", "myValue");
cookie.setMaxAge(60 * 60);
cookie.setDomain(".foo.com");
So from now on there will be only one cookie: 'foo.com' and the values will be save on the same cookie.
The problem is for old users, for them there will be two cookies ('www.foo.com' and 'foo.com'), how can i merge those two cookies to one??
One more thing, users from 'test.foo.com' eventually will visit 'www.foo.com' and vise versa.
Get the old cookie from the http servlet request, then set its max age to 0. That will trigger the client side to get rid of it (in its own time, normally right away). Also, see the Javadoc on Cookie.
setMaxAge
public void setMaxAge(int expiry)
Sets the maximum age in seconds for this Cookie.
A positive value indicates that the cookie will expire after that many seconds
have passed. Note that the value is the maximum age when the cookie will expire,
not the cookie's current age.
A negative value means that the cookie is not stored persistently and will be
deleted when the Web browser exits. A zero value causes the cookie to be deleted.
Parameters:
expiry - an integer specifying the maximum age of the cookie in seconds;
if negative, means the cookie is not stored; if zero, deletes the cookie
See Also:
getMaxAge()
You will need to parse through your cookies and search for the one you are trying to get rid of. Something like this:
final Cookie[] cookies = request.getCookies();
for(Cookie cookie: cookies) {
if("www.foo.com".equals(cookie.getDomain()) cookie.setMaxAge(0);
}

how to add data in cookie

I want to add two values in cookie and retrieve them. I am doing in this way, but I am getting only the first value, not the second.
Cookie c = new Cookie("a", a);
c.setMaxAge(60);
response.addCookie(c);
Cookie b = new Cookie("d", d);
b.setMaxAge(5 * 60);
response.addCookie(b);
While reading:
Cookie cookies[] = getRequest().getCookies();
Cookie myCookie = null;
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
log.info("test ;;;"+cookies[i].getName());
}
}
This returns only one data.
You are likely reading them from the wrong request. The newly added cookies will only be available in the subsequent requests, they will not be reflected immediately in the current request. So if you for instance add a cookie to the response and then tries to read it from the current request (the one associated with the very same response where you added the cookie to), then you won't get the added cookie at all. This also applies when you're forwarding the request from one to other resource (i.e. Servlet or JSP).
Debug/read the request/response headers in the client side as well for the sake that. In FireFox you can use the Firebug for this (open the Firebug pane, go to tab Net, click the request in question and you'll see both the request/response headers, the cookies are in there as well).
I would implement something like:
for(int i= 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
log.info("name: " + cookie.getName())
log.info("value: " + cookie.getValue())
}
This should print name and values of the cookies. If this is not working, probably the cookies are not added correctly to the response. Check that the cookies length is the one expected.
You can do some thing like this dear, I have tested it and its working
response.addCookie(new Cookie("name","sunny"));
response.addCookie(new Cookie("pwd","sunnymehta"));
Cookie[] cookie=request.getCookies();
for(Cookie ck:cookie)
{
System.out.println(ck.getName());
}
I would take a look at the actual cookie being saved in your browser. The first thing that comes to mind is the fact that in the underlying file that stores your cookie data, there is actually only one file -- the cookie objects in your code are actually being encoded as name-value pairs in a single file. The article at http://www.quirksmode.org/js/cookies.html has some good detail on how the data is actually stored in the cookie file. (Actually more than name-value pairs, since it also accomodates the other cookie properties like the expiration date and the secure flag, but anyway the article will show you that format.)
I gather that your java calls should be writing a validly formatted cookie file, and generating a valid array of cookie objects for you. But the fact that you're getting one object back seems suspicious to me in light of the underlying data format of the cookie.
In the past I've used Cookie Pal to inspect raw cookie data, though the site mentions IE6 support so I guess it's a little out of date.

Categories