How to retrieve existing cookies? - servlets

I have to create a new cookie if the cookie does not already exist. If the cookie already exist, then I should not override it, but just return it.
How can I verify whether the cookie exists or not? I have looked at javax.servlet.http.Cookie API, but I couldn't find any clues.
How can I retrieve and validate existing cookies?

You can get all cookies by HttpServletRequest#getCookies().
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
// ...
}
}
Note that this already contains only valid (non-expired) cookies. The browser namely already won't send expired cookies along the request.

Related

How can i keep users logged in when they return? [duplicate]

HI
I am using asp.net mvc with asp.net membership.
I want to have a checkbox that if clicked keeps the users signed in for 2 weeks(unless they clear their cookies).
So I know their is
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie)
but I don't know how to set it up for 2week retention.
I rewrote most of the membership stuff. So I don't use stuff like Create() and VerifyUser().
Add a hash key or a random string to both the cookie and the database (both the same key). If the cookie and database value are the same, when the user starts a new session, sign him/her in again. When the user reaches the two weeks, remove the secret key from the database using a cronjob (Unix) or scheduled task (Windows).
Warning: Do not rely on the cookie expire date, since people can hack their browser.
Rule: NEVER, EVER trust ANY of your users!
You can set the global session timeout (the value is in minutes) in web.config eg.
<system.web>
<authentication mode="Forms">
<forms timeout="20160"/>
</authentication>
</system.web>
This will be for all authenticated users. If you want to use the 'Remember Me' functionality then you will need to write your own code to set the cookie/ticket. Something like this (taken from here):
protected void Page_Load()
{
if (Request.Cookies["username"] == null || Request.Cookies["username"].Value.ToString().Trim() == "")
{
Login1.RememberMeSet = true;
}
else
{
Login1.UserName = Request.Cookies["username"].Value.ToString().Trim();
Login1.RememberMeSet = true;
}
}
protected void RememberUserLogin()
{
// Check the remember option for login
if (Login1.RememberMeSet == true)
{
HttpCookie cookie = new HttpCookie("username");
cookie.Value = Login1.UserName.Trim();
cookie.Expires = DateTime.Now.AddHours(2);
HttpContext.Current.Response.AppendCookie(cookie);
Login1.RememberMeSet = true;
}
else if (Login1.RememberMeSet == false)
{
HttpContext.Current.Response.Cookies.Remove("username");
Response.Cookies["username"].Expires = DateTime.Now;
Login1.RememberMeSet = false;
}
}
Just use a simple cookie with 2 weeks expiration date.
Have you seen this?
http://forums.asp.net/t/1440824.aspx
Along similar lines to what Koning has suggested.
You can not use a session method to keep your users logged in, since browsers delete the session cookies when the browser is closed.
Do what user142019 offered and set the session's IdleTimeout parameter very short, up to 15 min. When the server receives any request from the browser, first check the session if it's alive. if not, try to get the cookie. If the cookie and database value are the same and not expired, assign it to the (new) session and return the response.
You can use onBeforeUnload listener to send a logout request when the user leaves your site. If logged out, delete the cookie and the db record, if not - assign a new hash for the next auto login and refresh that hash again when the user retunes to your website. You can also keep track of IP and the browser and link them to the hash in your db.
So, in case if the cookie is used with another browser or IP, and the hash code is valid, you can force them to login again.

I can't read cookies in master or other pages

I create some cookies in logon.aspx.cscodebehind thatc read and contain user info from DB with data reader .
HttpCookie UID = new HttpCookie("ID");
Response.Cookies["UID"].Value = Recordset[0].ToString();
Response.Cookies.Add(UID);
HttpCookie UName = new HttpCookie("Username");
Response.Cookies["Username"].Value = Recordset[3].ToString();
Response.Cookies.Add(UName);
HttpCookie Pass = new HttpCookie("Pass");
Response.Cookies["Pass"].Value = Recordset[4].ToString();
Response.Cookies.Add(Pass);
HttpCookie Admins = new HttpCookie("Admin");
Response.Cookies["Admin"].Value = Recordset[12].ToString();
Response.Cookies.Add(Admins);
HttpCookie Mails = new HttpCookie("Emails");
Response.Cookies["Emails"].Value = Recordset[9].ToString();
Response.Cookies.Add(Mails);
Response.Redirect("../default.aspx");
when i trace the code every thing is good and data hold by cookies.
Now when i read these cookies in master page or other content page, i can't.
in other worlds the cookies not recognize by their names(or keys)
if (Request.Cookies["Username"] !=null)
{
lblWelcomeUser.Text = Server.HtmlEncode(Request.Cookies["Username"].Value);
pnlUsersNavigation.Visible = true;
LoginMenu.Visible = false;
RegisterMenu.Visible = false;
lblWelcomeUser.Text = Server.HtmlEncode(Request.Cookies["Username"].Value);
//lblWelcomeUser.Text = Request.Cookies["Username"].Value.ToString();
if (Request.Cookies["Admin"].Value.ToString()=="True")
{
lblWelcomeUser.Text = "WELCOME ADMIN";
// Show Menu that is only for Admin
}
where is the problem in this code?
It appears that you might be overwriting the cookie with a good value, with a new empty cookie.
// new cookie created - empty
HttpCookie UName = new HttpCookie("Username");
// new cookie created with a value
Response.Cookies["Username"].Value = Recordset[3].ToString();
// overwrite new cookie with value with new empty cookie
Response.Cookies.Add(UName);
Create the cookie, set the value, then add the cookie to the response.
HttpCookie UName = new HttpCookie("Username");
UName.Value = Recordset[3].ToString();
Response.Cookies.Add(UName);
Also note that as Paul Grimshaw pointed out, you can add multiple values to the same cookie.
Download Fiddler to check request/response to ensure your cookies contain the correct values and such... http://fiddler2.com/get-fiddler
Also be careful about Man-in-the-middle attacks. Storing usernames and passwords in plain text is not such a good idea to begin with.
This doesn't look like a very secure way of securing access to your application. Try looking at ASP.NET membership.
Otherwise try setting an expiry date. Also, as this example shows, you may want to store all the above info in one cookie:
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["UID"] = Recordset[0].ToString();
myCookie["Username"] = Recordset[3].ToString();
//...etc...
myCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(myCookie);
Also, from MSDN:
By default, cookies are shared by all pages that are in the same
domain, but you can limit cookies to specific subfolders in a Web site
by setting their Path property. To allow a cookie to be retrieved by
all pages in all folders of your application, set it from a page that
is in the root folder of your application and do not set the Path
property. If you do not specify an expiration limit for the cookie,
the cookie is not persisted to the client computer and it expires when
the user session expires. Cookies can store values only of type
String. You must convert any non-string values to strings before you
can store them in a cookie. For many data types, calling the ToString
method is sufficient. For more information, see the ToString method
for the data type you wish to persist.

cookie isn't updated until page refresh... how to avoid that?

I have some asp.net pages that read and write cookie values. During the life cycle of a page it may update the cookie value and then need to read it again further in the code. What I've found is that it's not getting the latest value of the cookie until a page refresh. Is there a way around this? Here's the code I'm using to set and get the values.
public static string GetValue(SessionKey sessionKey)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
return string.Empty;
return cookie[sessionKey.SessionKeyName] ?? string.Empty;
}
public static void SetValue(SessionKey sessionKey, string sessionValue)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
cookie = new HttpCookie(cookiePrefix);
cookie.Values[sessionKey.SessionKeyName] = sessionValue;
cookie.Expires = DateTime.Now.AddHours(1);
HttpContext.Current.Response.Cookies.Set(cookie);
}
What you're missing is that when you update the cookie with SetValue you're writing to the Response.Cookies collection.
When you call GetValue you're reading from the Request.Cookies collection.
You need to store the transient information in a way that you access the current information, not just directly the request cookie.
One potential way to do this would be to writer a wrapper class that with rough psuedo code would be similar to
public CookieContainer(HttpContext context)
{
_bobValue = context.Request.Cookies["bob"];
}
public Value
{
get { return _bobValue; }
set {
_bobValue = value;
_context.Response.Cookies.Add(new Cookie("bob", value) { Expires = ? });
}
}
I ran into needing to do similar code just this week. The cookie handling model is very strange.
Start using Sessions to store your information, even if it's only temporary.
Cookies rely on a header being sent to the browser before the page has rendered. If you've already sent information to the client then proceed to set a cookie, you're going to see this "page refresh delay" you've described.
If it's necessary to have this value, use a session variable between the time you set the cookie and when you refresh the page. But, even then I would just recommend avoiding settings cookies so late in the processing step and try to set it as early as possible.

ASP.NET Cookie Update Value Without Updating Expiration?

Is it possible to update an ASP.NET cookies value without also having to update the expiration time? I have found that if I try and update a Cookie without also updating the expiration, that cookie no longer exists. I have the following code which I am try to modify. What's the point of having an expiration, if every time the cookie value is updated, so is the expiration?
HttpCookie cookie = HttpContext.Current.Request.Cookies[constantCookie];
if (cookie == null)
cookie = new HttpCookie(constantCookie);
cookie.Expires = DateTime.Now.AddYears(1);
cookie.Value = openClose;
HttpContext.Current.Response.Cookies.Set(cookie);
The ASP.NET HttpCookie class can not initialize the Expires property upon reading in a cookie from an HTTP request (since the HTTP specification doesn't require the client to even send the Expiration value to the server in the first place). And if you don't set the Expires property before you set the cookie back in the HTTP Response, than it turns it into a session cookie instead of a persistent one.
If you really must keep the expiration, than you could set the initial expiration date as part of the cookie value, then when you read the cookie in, parse out the value and set the new expiration to match.
An example that doesn't include any other data so the cookie isn't really helpful -- you would have to serialize it somehow with the actual data you want to store:
HttpCookie cookie = HttpContext.Current.Request.Cookies[constantCookie];
DateTime expires = DateTime.Now.AddYears(1);
if (cookie == null) {
cookie = new HttpCookie(constantCookie);
} else {
// cookie.Value would have to be deserialized if it had real data
expires = DateTime.Parse(cookie.Value);
}
cookie.Expires = expires;
// save the original expiration back to the cookie value; if you want to store
// more than just that piece of data, you would have to serialize this with the
// actual data to store
cookie.Value = expires.ToString();
HttpContext.Current.Response.Cookies.Set(cookie);

How do I Keep a user logged in for 2 weeks?

HI
I am using asp.net mvc with asp.net membership.
I want to have a checkbox that if clicked keeps the users signed in for 2 weeks(unless they clear their cookies).
So I know their is
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie)
but I don't know how to set it up for 2week retention.
I rewrote most of the membership stuff. So I don't use stuff like Create() and VerifyUser().
Add a hash key or a random string to both the cookie and the database (both the same key). If the cookie and database value are the same, when the user starts a new session, sign him/her in again. When the user reaches the two weeks, remove the secret key from the database using a cronjob (Unix) or scheduled task (Windows).
Warning: Do not rely on the cookie expire date, since people can hack their browser.
Rule: NEVER, EVER trust ANY of your users!
You can set the global session timeout (the value is in minutes) in web.config eg.
<system.web>
<authentication mode="Forms">
<forms timeout="20160"/>
</authentication>
</system.web>
This will be for all authenticated users. If you want to use the 'Remember Me' functionality then you will need to write your own code to set the cookie/ticket. Something like this (taken from here):
protected void Page_Load()
{
if (Request.Cookies["username"] == null || Request.Cookies["username"].Value.ToString().Trim() == "")
{
Login1.RememberMeSet = true;
}
else
{
Login1.UserName = Request.Cookies["username"].Value.ToString().Trim();
Login1.RememberMeSet = true;
}
}
protected void RememberUserLogin()
{
// Check the remember option for login
if (Login1.RememberMeSet == true)
{
HttpCookie cookie = new HttpCookie("username");
cookie.Value = Login1.UserName.Trim();
cookie.Expires = DateTime.Now.AddHours(2);
HttpContext.Current.Response.AppendCookie(cookie);
Login1.RememberMeSet = true;
}
else if (Login1.RememberMeSet == false)
{
HttpContext.Current.Response.Cookies.Remove("username");
Response.Cookies["username"].Expires = DateTime.Now;
Login1.RememberMeSet = false;
}
}
Just use a simple cookie with 2 weeks expiration date.
Have you seen this?
http://forums.asp.net/t/1440824.aspx
Along similar lines to what Koning has suggested.
You can not use a session method to keep your users logged in, since browsers delete the session cookies when the browser is closed.
Do what user142019 offered and set the session's IdleTimeout parameter very short, up to 15 min. When the server receives any request from the browser, first check the session if it's alive. if not, try to get the cookie. If the cookie and database value are the same and not expired, assign it to the (new) session and return the response.
You can use onBeforeUnload listener to send a logout request when the user leaves your site. If logged out, delete the cookie and the db record, if not - assign a new hash for the next auto login and refresh that hash again when the user retunes to your website. You can also keep track of IP and the browser and link them to the hash in your db.
So, in case if the cookie is used with another browser or IP, and the hash code is valid, you can force them to login again.

Resources