Scenario:
I am setting Cookies in page https://www.example.com/#step1 by using method:
Cookies.setCookies("firstFileName","NewDocument");
Cookies.setCookies("firstFileExt","doc");
Users are supposed to click next and redirect themselves to https://www.example.com/#step2 . But in Case, user click to some other menu (like Home, About us, Contact us), I am deleting these Cookies by using the following method:
Cookies.removeCookie("firstFileName");
Cookies.removeCookie("firstFileExt");
But on removing I found that these two Cookies still holding the values in browser, When I do the following in https://www.example.com/#step1 before setting these two Cookies:
if(!Cookies.getCookie("firstFileName").toString().equals("undefined")){
Window.alert("firstFileName "+firstFileName);
}
I get an alert box that firstFileName NewDocument
Please let me know how can I set and remove the Cookies in my Case.
If you set a cookie without providing a path, as you do using Cookies.setCookies("firstFileName","NewDocument");, the cookie can only be removed on the same page.
A solution would be to always set the cookie for a specific path like that:
// TODO: set expiration time to something more useful
Date expires = new Date();
Cookies.setCookie("firstFileName","NewDocument", expires, null, "/", false);
Then you can remove it by calling that later on:
Cookies.removeCookie("firstFileName", "/");
As your application is based on the relative path "/", every page can set or remove the cookie and all pages access the same cookie value.
If you just set the cookie without providing a path, two pages of your application could even set different cookies.
Related
I have a java web application. I implemented a login system, with user rights a while ago, and included a "remember-me" functionality with unique string ID's saved client side in cookies.
This has worked ok, except for the fact that the remember me functionality always fails on first page load whenever a new session starts. However, since most users access a non-restricted page first, complaints has been absent. Nonetheless, I'd like to fix it. Here is what I have learned.
I use implementations of javax.servlet.Filter to check if a user has rights to se a page. for example baseURL/pages/admin/*. Filter interface has a method called doFilter, which accepts a ServletRequest, and ServletResponse object as parameters. I cast these to HttpServletRequest and HttpServletResponse. The HttpServletRequest gives me access to cookies and session.
If i iterate through the cookies, I find my "remember"-cookie, with the unique ID as a value. However, this ID is wrong.
Now, in my Servlet class, which follows the front controller pattern, I also have a check for user logged in, and remember me. But because this is executed after the filter, it is not sufficient to check only here. Still, I do want to check for every page, even if it is not restricted, as it changes the layout slightly if you are logged in.
The java HttpServlet service method accepts a HttpServletRequest and HttpServletResponse object. In other words, no need for casting here. Funny thing is though, If i try to access my cookies from here, it will give me an identical id for the session cookie, but a completely different uid for my "remember"-cookie.
I have found that my system adds new remember cookies for each of my filters. And if I try to access a page in the admin path, both cookies from /webapp/pages, and cookie from /webapp/pages/admin will be present in chrome inspector. When accessing the cookies in the filter, the /webapp/pages/admin is the only one that will exist. Oppositely, the /webapp/pages is the only one that will exist in the front controller servlet service method.
I guess this is because of the mapping of said filter and servlet, which matches the path of the cookie. The problem is that I never intended there to be cookies stored hierarchically, and only want the one to be stored, at /webapp/pages. My system has now stored plenty of these deeper pathed cookies all over my client network, and whenever a user logs in and out, they might get out of sync with a new uid.
Is there a way I can force retrieving the /webapp/pages cookie over the /webapp/pages/admin cookie? Or is there a way to retrieve both? I could just check both uid's for a match if I can manage that (hence the title of my question)
For the future, I have made sure to set the path of cookie storage, so that the same path will be used, but as the cookies has a year to expire, this will not solve my problems for a long time, unless I find a way to check the correct cookie.
The answer to the title question is; you can't.
The browser will decide which cookies it deems most relevant, and there is nothing you can do to change that. When your filter is mapped to a subpath, and servlet is mapped to a higher path, you will get the best matching cookie for each path.
The specific problem in the question text is caused by a bad coding pattern. The remember me cookies should be stored at a specific path when created, in this case /webapp/pages. This will prevent the cookie from being created as multiples, in hierarchical paths.
There is still the problem of already existing cookies client side. These can be handled by adding the following javascript in a central area of your code, somewhere where you'd know that all users will encounter it:
document.cookie = 'remember=; path=/webapp/pages/user; expires=' + new Date(0).toUTCString();
document.cookie = 'remember=; path=/webapp/pages/admin; expires=' + new Date(0).toUTCString();
This will set the unwanted cookies to expire at an already past date, effectively deleting it.
Now only one cookie with name "remember" will exist for the domain, and both servlet and filters will fetch the same cookie, regardless of their mapped subpaths.
IWS is a desktop application with its own webBrowser component to call Scripting web-app when needed. Scripting is located in a Tomcat6.
Scripting is basically an JSP application. (Really it is an engine who builds an JSP application from the human actions over its graphical interface, like define flows, buttons, content, etc, but I am talking about the "Script" it generates as an JSP)
I need to hack Scripting so it can share space (via frames) in that webBrowser component of IWS application.
The IWS call 2 times to start.jsp:
the first time, in a hidden way (probably a direct http query from IWS code), without any special parameters. The original start.jsp do 2 302 (so the call visits 3 pages total) it ends using the jsesionId both in cookie and as a parameter (but not at the last 302)
second time, with the jSessionId and a bunch of important parameters. It only uses the jSessionId as the parameter. As far as I have seen in fiddler, no cookie is used when it works correctly as jsessionId is inside its own
So I guess that the first time ìt is just to get a new jSessionId.
The solution I am trying now is to replace Scripting starting page with a new frames page which, in one of the two frames it holds, it loads the web aplication, and another application in the second frame. Depending on data from the first frame it will update the second frame.
So something like to:
we had start.jsp... (really it is called something different)
and we end with:
start.app.jsp (which is original start.jsp, just renamed)
start.jsp (is the new including html which wraps the previous start.jsp)
The new start.jsp uses its own url, changing start.jsp into start.app.jsp, to invoke the true Scripting application inside an iframe.
But I have been suffering from like session problems. I am not an expert in tomcat. I learned that it controls the session with cookies or with parameters. I think it is configured to work with the URL sessionId but I am not really sure. I have set META-INF/settings.xml to disable cookie use in sessions, but it still show the cookie in the cookies list.
My problem is that in that second time start.jsp is called, it appear than somethink like an "old cookie" is being used, ignoring the jsessionId from the URL. Some weird errors appear at WWG00000E: WWGAIL - Error: ID was not provided for function getInteractionKVPair Detail:
It is like it is returning to an old cookie with another jsessionid. That 'old' jsessionid is the same each time the error shows up.
Sniffing with fiddler, I see that the second start.jsp starts with the right jsessionId in the URL, but its cookies are like from another session, and it stops to add the jsession id with each redirection since this happens. It is like it is executing in a completely different universe. Is this normal?????
Currently I am trying without avail to force the cookie jSessionId and also the links so they include the jSessionId.
Please, do you have any idea?
Thanks!
Edited2: if I place it without frames (restoring default start.jsp). At IWS works only the first time (interaction), while in any subsequent one the problem start to appear...
Ok, solved at last...
At least with this version of Tomcat:
A call to a jsp without jSessionId creates a new jSessionId in your app cookie.
Any further on in time html request will use the cookie jSessionId instead of the one present on the URL, so you lose any type of multisession support.
It is something special than in a webBrowser component, doing a two steps connections, the first request never have an associated cookie, so it works OK, giving you a cookie with a new jSessionId, and then you can do a new, cookieless, second request which uses the jSessionId of the URL and have not cookie or have "a default" cookie without jSessionId. When this webBrowser requests a jsp page without jSessionId in its URL, as said, the problem starts, so if the first request includes a non jSessionIded call, Tomcat gives you a jSessionId which is set on your "default app cookie", so the second request ignores any URL jSessionId to use the one on that cookie.
In a web browser, I have observed that in at least firefox, cleaning the cookies is not enough to eliminate this "default cookie". But maybe it could be the classic "It takes too long so you think it is clean but really it is not". Not sure.
I know this sounds confusing. I have not the time to do further testing about this.
As far as I have understood, it is like, when it works OK, it is working like with an "session cookie" (without jSessionId), while when it does not work it takes the "default cookie" (with jSessionId) and starts ignoring URL jSessionId.
I have sent an email to the dev mailinglist of Tomcat. (One said that the correct place was the user mailinglist... but here you are ;-) )
For example in gmail login, when we consider a login test, when doing it manually for the first time we'll get the login page, from next time onwards we'll be directly getting into the inbox page.
If you try to do the same thing in webdriver(Run login test twice), in all these attempts we'll get the login page as we didn't login from this machine earlier. What is happening in behind the scenes in maintaining the session with respect to cookies or session ?
Here is the description & code snippet from selenium docs to add or remove cookies:
Before we leave these next steps, you may be interested in
understanding how to use cookies. First of all, you need to be on the
domain that the cookie will be valid for. If you are trying to preset
cookies before you start interacting with a site and your homepage is
large / takes a while to load an alternative is to find a smaller page
on the site, typically the 404 page is small
(http://example.com/some404page)
// Go to the correct domain
driver.get("http://www.example.com");
// Now set the cookie. This one's valid for the entire domain
Cookie cookie = new Cookie("key", "value");
driver.manage().addCookie(cookie);
// And now output all the available cookies for the current URL
Set<Cookie> allCookies = driver.manage().getCookies();
for (Cookie loadedCookie : allCookies) {
System.out.println(String.format("%s -> %s", loadedCookie.getName(), loadedCookie.getValue()));
}
// You can delete cookies in 3 ways
// By name
driver.manage().deleteCookieNamed("CookieName");
// By Cookie
driver.manage().deleteCookie(loadedCookie);
// Or all of them
driver.manage().deleteAllCookies();
I'm new to Java. I'm writing an application to link to a vendors Flash site. I have my BlazeDs based program talking to their site. I'm running into a problem where a session cookie is not getting set. The problem is that the host doesn't return it as a "set-cookie" header.
Their site returns the following cookieDirectives to set the SMSESSION cookie
cookieDirectives
Externalized Object
flex.messaging.io.ArrayCollection
[0] String SMSESSION={CONTENT STRIPPED FOR CLARITY}; max-age=-1;path=/; domain=.-----.com
I can set the cookie in my amfConnection as follows:
amfConnection.addHttpRequestHeader("Cookie", resultString);
However, that only gives me the one cookie and there are several others I need. The others have been set earlier by the host and are set using a "Set-Cookie" header.
How can I either add this cookie to the existing ones or recover the existing cookies so I can manually add them.
I was able to resolve this by changing my approach. Instead of relying on my amfConnection to handle the cookies I grab the session id using httpclient, store it in a variable, and then push my cookies to amfConnection.
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.