I'm having an issue with deleting cookies from my servlet code. Given bellow is my code.
private void clearCookies(HttpServletRequest req, HttpServletResponse resp) {
Cookie[] cookies = req.getCookies();
for (Cookie curCookie : cookies) {
curCookie.setValue(null);
curCookie.setMaxAge(0);
curCookie.setPath("/");
resp.addCookie(curCookie);
}
}
I do a resp.sendRedirect(url) after this method call. However, not all cookies get deleted, for example this cookie never get deleted.
Name: reqURI
Content: ../../webapp/index.jsp
Domain: mgt.appserver.com
Path: /
Send for: Any kind of connection
Accessible to script: Yes
Created: Tuesday, November 26, 2013 4:35:19 PM
Expires: When the browsing session ends
Does anyone knows what I'm missing here? I read the Java Cookie object documentation and according to that value 0 should make the cookie to be removed. But it's not. And I tried many more suggestions and none of it worked. I tried this with Google Chrome and Firefox, so can't believe it's an issue with the browsers. I have no idea why such a generic thing is not properly documented and complected in a language like Java.
Update
As per Problem removing cookie in servlet
The path and domain will always be null when you retrieve cookies in Java because they are only necessary in the response for the client browser. However, if you're in the same security domain (regardless of the path), you still have the rights to delete them. Unfortunately, because the path is not included you can't delete the cookie now without explicitly knowing that path. Simply using the same cookie name, but a different path will not work. Those are considered two different cookies, and you will find that instead of deleting the cookie, you just created another one on a different path.
So you should not change value or path as this will create a new cookie
Where are you redirecting? The response has to be committed back to the host that created the cookie in the first place in order for it to be removed. Also, you don't need to set the value to null.
Related
I've browsed a bunch of questions that are similar to mine, but none of the solutions I have tried seem to work.
I have a Jersey2.0 REST service that adds a cookie to the response and returns it to an Angularjs front end application. I already have the setup done correctly (Access-Control-Allow-Credentials=true, no wildcard in Access-Control-Allow-Origin, etc..).
I do it by adding a "SET-COOKIE" header on the response like so:
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("SET-COOKIE", new NewCookie(cookieName, cookieValue);
This works, and I can see the cookie being returned in the response of that particular REST service call to that particular REST endpoint. What I mean is, on the Chrome developer console under the Network tab, I can click on the request that is supposed to return the cookie, and in both the 'Cookies' and 'Headers' tabs, I can see the cookie being returned in the response. In fact, when I make another request to the endpoint, that same cookie is now sent in the request and I can capture it on the Jersey server.
Great. The issue is that the cookie is not showing up on the 'Resources' tab. If I click on the 'Resources' tab, then along the left select the 'Cookies' dropdown and then select localhost, the cookie I'm trying to send in the response is not there. I'm assuming this is also why when I try to get the cookie in my AngularJs application via $cookies.get('cookieId'); using ngCookies, I get undefined.
Also, just in case someone mentions it in an answer/comments, I'm pretty sure the problem here is not HttpOnly. My JSESSIONID cookie gets returned, and I can see it in the 'Resources' tab with the Http field checked indicating HttpOnly.
I thought maybe because I'm in a corporate environment, they don't let me add cookies, but I'm able to do this on the Angular front end via $Cookies.put('cookieId', 'cookieValue'); and it shows on the 'Resources' tab just fine.
Any help as to why my cookies are not being added from the server?
After digging through a few more stackoverflow questions relating to my original one, I found out through this stackoverflow question that cookies that are created on one domain cannot be accessed on another domain using Javascript.
I will have to come up with a workaround for this, but my original question has been answered so marking this as answered.
For your case it is easy to solve if you just set the path of the cookie,
e.g.
Cookie myCookie = new Cookie("Name_of_cookie", "String_value_of_cookie")
myCookie.setPath("/the domain Js is using ")
Or just leave it as / for the main domain that most probably Js is deployed.
Background:
I programmed 2 ZK web applications (ZK653CE) with netbeans 8.1 both are moduls for a single task.
Now I want to access application B from within application A both projects are on the same Tomcat 8 webserver.
Why I want to do this:
Application A has a user login and presents data to the user. Application B allows anybody to create a pattern for displaying data. I want a user to start application B and create a pattern (Press save close app). This pattern shall be send back to application A that then changes the display behaviour of the data to the new pattern. I do not want to mix those 2 applications together, because I want them to stay independent.
What I already figured out while searching this topic:
It is not possible to directly access an external webapp from within a zk project
It would be possible to use a shared ressource concept from tomcat (but I don't want that because I want this to run on different webservers like glasfish and others)
The real question:
Is there a way to have both apps independent (if yes please explain or show an example) or do I have to merge them?
I had much time to try differnt things I'll show the 2 best solutions I came a cross:
Using Cookies
One can use Cookies to store data at the client and use the server to access it. It's commonly used for sessionmanagement or other parts that control the content for the current user.
To access Cookies one would use this code in a ZK Class (Controller or Viewmodel):
HttpServletRequest req = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
Cookie[] cookies = req.getCookies();
This will load all cookies of the current session. The HttpServletRequest class can be found in the java docs for more information (it represents the raw client http request). One can then iterrate through the array and look for a Cookie
HttpServletResponse resp = (HttpServletResponse) Executions.getCurrent().getNativeResponse();
for(Cookie c : cookies) {
if(c.getName().equals(COOKIE_MODE)) {
externalAccess = Boolean.parseBoolean(c.getValue());
c.setMaxAge(0);
c.setValue(null);
c.setPath(NAMESPACE);
resp.addCookie(c);
}
}
externalAccess stores if the modul was loaded from an external modul. This external module would have to create that Cookie first of course. The set parameters are used to delete the Cookie setting the age to 0 means its expiered one also sets the value and if a path was used to create it one must also set the path because it must be known where the old Cookie was placed. The cookie must be added to a HTTP Response for the client (from the server) so that the client replaces its old Cookie.
To create a cookie one would use this:
Cookie cookie = new Cookie(COOKIE_NAME, COOKIE_VALUE);
cookie.setPath(NAMESPACE);
HttpServletResponse resp = (HttpServletResponse) Executions.getCurrent().getNativeResponse();
resp.addCookie(cookie);
This is very similar to the for loop before.
Approach
Just add a parameter to the URL (commonly used to provide parameters):
If one hase a webserver on localhost its address is probably this:
http://localhost:8080/
a modul is loaded to / or if a subfolder is specified /modul
if one has a .zul in /modul named index.zul
one can access it by using http://localhost:8080/modul/index.zul
if one want's to add a parameter it would be done like this:
http://localhost:8080/modul/index.zul?externalAccess=1
one can then access this in the viewmodel or controller of index.zul (i used MVVM) with the following code:
String external = Executions.getCurrent().getParameter("externalAccess");
One can then cast the parameter to ones liking.
To create a redirect that uses the URL above one can use this:
Executions.sendRedirect("http://localhost:8080/modul/index.zul?externalAccess=1");
one can get the URL to ones server and the current application like this:
Server:
String server = Executions.getCurrent().getScheme() + "://" + Executions.getCurrent().getServerName() + ":" + Executions.getCurrent().getServerPort();
For the path to the application starting with "/":
Executions.getCurrent().getContextPath() + Executions.getCurrent().getDesktop().getRequestPath();
One could also use a config file that has the URLs stored (on webserver) but i won't cover that here
I want to delete a Cookie through Java Code which I have written like,
Cookie[] cookies = request.getCookies(); //request - HttpServletRequest
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("cam_passport")) {
cookies[i].setMaxAge(0);
cookies[i].setValue("");
response.addCookie(cookies[i]);
}
}
I am getting the list of cookies in the "cookies" object but not the required one "cam_passport".
What I have observed is, the PATH of this Cookie is different when I checked in Mozilla.
Where as, the list of Cookies which I am getting in my 'cookies' object have their path as "/".
And, for this "cam_passport" cookie, path is "/cognos10".
I need the above cookie to be deleted at one instance every time. How can I get the Cookies of different path like the above one?
You need to send a redirect to that path, perhaps along with a request parameter. You can then in a servlet or filter which is mapped on exactly that path obtain the cookie and delete it, if necessary based on presence of the request parameter. Finally you can redirect back to the original URL, if necessary based on a request parameter.
In the future, use cookie.setPath("/") during creating the cookie if you need the cookie to be available throughout the entire web application.
I'm trying to set the httponly flag on the JSESSIONID cookie. I'm working in Java EE 5, however, and can't use setHttpOnly(). First I tried to create my own JSESSIONID cookie from within the servlet's doPost() by using response.setHeader().
When that didn't work, I tried response.addHeader(). That didn't work either. Then, I learned that the servlet handled converting the session into a JSESSIONID cookie and inserting it into the http header so if I want to play with that cookie, I'll have to write a filter. I wrote a filter and played with setHeader()/addHeader() there, again to no avail.
Then, I learned that there's some flush/close action going on in the response object before it gets to the filter so if I want to manipulate the data, I need to extend HttpServletResponseWrapper and pass that to filterChain.doFilter(). This is done but I'm still not getting results. Clearly I'm doing something wrong but I don't know what.
I'm not sure if this is at all relevant to the question at hand but no html document is being returned by the servlet to the browser. All that's really happening is that some objects are being populated and returned to a JSP document. I've sort of assumed that The Session object is turned into a JSESSIONID cookie and wrapped -- along with the objects added to the request -- in an http header before being sent to the browser.
I'd be happy to post some code but I want to rule out the possibility that my difficulties stem from a misunderstanding of the theory first.
Since the JSESSIONID cookie is managed by the servletcontainer, this setting is servletcontainer specific. It's unclear which one you're using, so here's an Apache Tomcat 6.0 targeted answer so that you know in which direction you'll have to look for your servletcontainer: you need to set the useHttpOnly attribute of the webapplication's <Context> element to true.
<Context useHttpOnly="true">
...
</Context>
Also see this Tomcat documentation about the <Context> element.
You can use this with Java EE 5:
For Java Enterprise Edition versions prior to Java EE 6 a common workaround is to overwrite the SET-COOKIE http response header with a session cookie value that explicitly appends the HttpOnly flag:
String sessionid = request.getSession().getId();
// be careful overwriting: JSESSIONID may have been set with other flags
response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; HttpOnly");
Source : https://www.owasp.org/index.php/HttpOnly
I test it into a filter
I have found a strange behaviour (strange for me, a novice :D) in my project.
Basicly after an action I create or update a cookie (if it exists or not) and send it to the client. The strange thing is that in the jsp I can read the cookie ONLY when I update its value (and I get the updated value, not the old one) but not the first time, when I create it (I can see the cookie using a browser tool but seems that the jsp can't read it).
Is this a normal behaviour? If yes, what do you suggest to do in order to have the cookie information available also at the first time?
Thanks very much!
Roberto
If you create or update a cookie, it will be stored in the response header. If you request a cookie, it will be requested from the request header.
I think your problem is that you're forwarding the same request from servlet to JSP and that you expect that the new cookie is already available in the request header. This is not true. The new cookie is only available in the subsequent requests.
You have 2 options:
Redirect to JSP. A redirect will create a new request.
Store the data of interest as request attribute and let EL in JSP access it.
By the way, I saw in one of your comments that you're using plain Java code to read cookies in a JSP. I would only say that using scriptlets in JSP is a bad practice. You can access cookie values easily in EL as follows:
${cookie.cookiename.value}
[Edit] oh my, now I see that this is an old topic. Hopefully my effors weren't all for nothing :/
Cookies are stored on client, and so if the response doesn't gets to the client yet, its value is not updated, but it should be available on the next requests.
cookies are used to identify clients when they send you any requests. here's what you are doing when you set the cookie up. you are sending the cookie to the client along with response. And when that client send his next request the cookie that you set comes along with it. so, in the jsp page where you are setting up the cookie, you don't have a request from the client with cookie! so you can't read it. but what you can do like what jerjer has said above. (i.e use a temp and store cookie's value in it and don't try to retrieve cookie. just read the temp value). And i see you say you can read the cookie only when you update. You will be able to read cookie's value from future reqests after cookie is set even if you don't update it. Hope this helps.