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);
}
Related
Is there a maximum number of cookies which you can set on a single http response? If yes how many?
Because I'm trying to create 2 cookies in one response, for some reason only one is getting created. I'm using the code below.
Cookie cookie = new Cookie("wNote", "1530571761964");
cookie.setMaxAge(2592000);
cookie.setPath("/myWebsite/");
response.addCookie(cookie);
the other cookie is the JSESSIONID which is being created by the server automatically. In the response headers under Set-Cookie I can see only JSESSIONID.
Apache Tomcat 8.0.27
Google Chrome 67.0
If you are using Tomcat then, only one Cookie in HttpServletResponse.addCookie(javax.servlet.http.Cookie) But this method can call multiple times:
The servlet sends cookies to the browser by using the HttpServletResponse.addCookie(javax.servlet.http.Cookie) method, which adds fields to HTTP response headers to send cookies to the browser, one at a time.
This method can be called multiple times to set more than one cookie.
The browser is expected to support 20 cookies for each Web server, 300 cookies total, and may limit cookie size to 4 KB each.
Cookies Doc
Ok going more deeper about this cookies. I check the RFC 2109
Practical user agent implementations have limits on the number and
size of cookies that they can store. In general, user agents' cookie
support should have no fixed limits. They should strive to store as
many frequently-used cookies as possible. Furthermore, general-use
user agents should provide each of the following minimum capabilities
individually, although not necessarily simultaneously:
at least 300 cookies
at least 4096 bytes per cookie (as measured by the size of the
characters that comprise the cookie non-terminal in the syntax
description of the Set-Cookie header)
at least 20 cookies per unique host or domain name
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.
I need to create cookie with e-mail address as value - but when I try to - then I have result:
"someone#example.com"
but I would like to have:
someone#example.com
The cookie should be created without double quoted marks - because other application uses it in such format. How to force java to not to add double quoted? Java adds them because there is special char "at".
I create the cookie that way:
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
Cookie cookie = new Cookie("login", "someone#example.com");
cookie.setMaxAge(2592000);
cookie.setDomain("domain.com");
cookie.setVersion(1);
response.addCookie(cookie);
Thanks for any help.
It's indeed caused by the # sign. This is not allowed in version 0 cookies. The container will implicitly force it to become a version 1 cookie (which breaks in MSIE browsers). You'd like to URL-encode the cookie value on cookie's creation
Cookie cookie = new Cookie("login", URLEncoder.encode("someone#example.com", "UTF-8"));
cookie.setMaxAge(2592000);
cookie.setDomain("domain.com");
response.addCookie(cookie);
and URL-decode it on cookie reading
String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
Note that you should for sure not explicitly set the cookie version to 1.
See also:
Why do cookie values with whitespace arrive at the client side with quotes?
Unrelated to the concrete problem, cookies are visible and manipulatable by the enduser or man-in-the-middle. Carrying the email address around in a cookie is a bad smell. What if the enduser changes it to a different address? Whatever functional requirement (remembering the login?) you thought to solve with carrying the email address around in a cookie should most likely be solved differently.
See also:
How do I keep a user logged into my site for months?
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.
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 ?