In a java web application,I want to check whether a user who signs in is a returning user. How can I check if there is already a cookie that has been set on earlier login.
On HttpServletRequest you have a getCookies() method that will give you an array of the cookies the client is sending with his request.
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getCookies%28%29
Set cookie when user performs log-in:
Cookie c = new Cookie("visit", "old")
c.setMaxAge(3600*24*365*1000); // 1 year (for example)
response.addCookie(new Cookie("visit", "old"));
Now you can check this cookie when user with new session comes to the system: request.getCookies(), then iterates over returned array and find "your" cookie. If cookie exists this is "old" user otherwise the new one.
Related
Suppose in my Java app I do
Cookie myCookie = new Cookie("myCookie", "someValue");
myCookie.setMaxAge(3); // 3-seconds
When a cookie is sent in the response it must have an Expiration Date. My understanding is it will expire on CreationDate + 3 sec (maxAge). maxAge is the delta.
If I create a cookie at 1/1/2020 16:08:00, is its Expiration Date 1/1/2020 16:08:03 ?
Then who sets the original Creation Timestamp of the cookie, is it the constructor? How is the overall date tracked?
The cookie creation time is not stored in the cookie. The client keeps the cookie for the given time, starting when it receives the cookie.
In addition to what #JB Nizet said, clients can also update any cookie-related information it receives from the server's Set-Cookie response header.
Test it yourself in Chrome's Dev Tools, "Application" tab, there's a "Cookies" node in the left panel. For every domain, it allows you to see and/or modify any cookies you have stored in your browser. If you choose to update the "Expires/Max-Age" to a date in the past, the browser will automatically remove that cookie. You can also update it to sometime further out in the future.
Therefore, it's ultimately up to the server to know if a cookie is actually "valid." You should never rely on the max-age/expires data coming from the client to determine true validity. Clients use this to simply know when to delete it from it's local storage.
I am stuck in cookie clean up issue.
We have created cookie value with domain : .www.parent.com
And later we changed code base to create cookie values in domain : .parent.com
This is giving us cookie values from both the domains and messing up with our code. Is there a way to delete cookies from .www.parent.com via java code ?
I have already tries doing like this :
Cookie cookie = new Cookie("oldCookie" , null);
cookie.setMaxAge(0); or cookie.setMaxAge(-1);
cookie.setPath("/");
response.addCookie(cookie);
You might want to get all the cookies the client has stored and check them, using request.getCookies(), which returns a Cookie array.
In that way, you'll need to check anyone for the wanted domain and set its TTL with something like this:
Cookie[] c=request.getCookies();
for(int i=0;i<c.length;i++){
if(c[i].getDomain().equals(".www.parent.com")){
c[i].setMaxAge(0);
response.addCookie(c[i]);
}
}
This way, the cookie you're passing to the response should have exactly the same name, path and any other attribute except for maxAge value being 0.
Right now, we have csrf token per session. And adding this token jsp's using hidden field. following snippet gives only one per session:
token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_NAME);
if (null==token) {
token = UUID.randomUUID().toString();
session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token);
}
and for every request,
//calls the above snippet and this time token will not be null
String st = CSRFTokenManager.getTokenForSession(request.getSession());
String rt = CSRFTokenManager.getTokenFromRequest(request);
here, usings equals to compare the strings and returning either true or false.
my question is, what happens if I try to generate the token for every request without getting the token from session. And while comparing, I will get from the session and request. is this good idea or missing something?
Instead of using the above snippets, I will go with following
//for every request generate a new and set in session
token = UUID.randomUUID().toString();
session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token);
//get the token from session and request and compare
String st = (String) request.getSession().getAttribute("CSRF_TOKEN_FOR_SESSION_NAME");
String rt = CSRFTokenManager.getTokenFromRequest(request);
You'll want to flip around the flow that you stated above. After every compare you should create a new token.
One large drawback to token-per-request is if the user hits the back button in their browser:
User visits Page1 and stores TokenA in session.
User clicks a link to Page2, submitting TokenA. The app verifies TokenA in session and gives the user TokenB.
User hits the back button to go back to Page1, session information is not updated.
Page1 still only has information for TokenA, user clicks a link or submits a form to Page3 submitting TokenA, but the session only knows about TokenB
App considers this a CSRF attack
Because of this, you need to take great care of how and when the tokens are updated.
Apart from the solution suggested by Jay, I will suggest you to avoid caching of your web-pages by setting various cache-control headers in the response to client.
I need to implement a simple remember me option in a java servlet with cookies, without using any advanced framework.
First, at login, I create the cookie and send it in response to the browser (client). The value to be stored in the cookie is just a simple hash from username + password.
How should I manage the incoming request from the browser, sending the cookie?
My approach is to check between registered users if there is any user that has the hash from username + password equal to the value in the cookie?
Is this approach correct?
Also, I did not understand exactly what is the mechanism of the expiration date. Does the browser delete the cookie when it is expired, it not, how do I check if the cookie is expired?
As long as you're not using HTTPS the method you suggest is highly insecure. I would suggest to generate some sort of session token (e.g. use java.util.UUID.randomUUID()) and set this as cookie and store it somewhere on the server side so you later can identify the user associated with this session id in the cookie.
This gives you the opportunity to reset a certain session cookie if you think there's some fraud happening and there's no direct relation between the user name/password and the cookie id you use. But note: this method is still vulnerable to a man-in-the-middle attack.
Concerning the expiration: yes the cookie becomes invalid and might get deleted by the browser if it is expired. But you can set the cookie to something in the year 3000, so it lives forever.
I am having a problem of setting the data of a (persistent/cross browser session) cookie correctly inside a Servlet and the reading it in a Filter.
the code of the Servlet (running at log-in time) is:
String encodedValue = new String(Base64
.encodeBase64(req.getParameter("account").getBytes()));
Cookie cookie = new Cookie("projectAuthenticationCookie", encodedValue );
cookie.setMaxAge(24*60*60);
cookie.setPath("/");
res.addCookie(cookie);
This will get the cookie inside the response, but the when I read it within my filter with the following code:
Cookie authenticationCookie = null;
Cookie[] cookies = ((HttpServletRequest) request).getCookies();
for (Cookie cookie : cookies){
if ("projectAuthenticationCookie".equals(cookie.getName())) {
authenticationCookie = cookie;
}
}
I only get the value I set right, all other fields are either null, empty or different. Max age for example always returns -1 and thus the cookie will never persist.
I tried setting the expires-header with:
res.setDateHeader("Expires", System.currentTimeMillis() + 24*60*60*1000);
as I read that without a valid expires-header the session will timeout anyway (correct me if I am wrong), but that didn't help either...
One issue I am thinking of is that I am running on localhost (tried setting cookie.setDomain("localhost") but also no luck). My web server/serclet container is Jetty 7 but I do not think that this is relevant...
Any hints?
The fields other than name and value are not populated (and thus not meaningful) on cookies you get from a request.
These fields are intended to inform the browser about the max age; path, etc. of the cookie, but the browser doesn't send back this information to the server. The only time where it's important to have the correct max age, path, etc. is when you create a cookie and add it to the response. Use your browser to check if it stores the correct information instead of trying to find it at server-side.