asp.net mvc 3 - set global user data
How can I set global user data that retain some information like name, lastname, etc through pages? If I use sessi开发者_运维问答on variable it expires before auth cookie
thanks!
You can store data for the time of auth session by utilising userdata field in auth cookie.
Code below is the LogOn action from AccountController in default MVC project:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
You can replace:
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
with:
string fullName = "User full name";
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, model.Email, DateTime.Now,
DateTime.Now.AddDays(2), model.RememberMe, fullName);
string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = DateTime.Now.AddDays(2) });
If you want to store more data than you can pack in a normal string you will have to look into some sort of data serializer.
Then, you will have to implement something to parse serialized data when auth cookie is used.
Data is available through:
((FormsIdentity)User.Identity).Ticket.UserData;
Hope that helps
Edit: Also change DateTime.Now.AddDays(2) to whatever you want your auth session to remain valid.
Session state may be configured in a variety of ways to address the issues above. Specifically, if using in-process session state (wherein state is maintained within the same application domain/pool as the running application), simply increase the timeout to be equal-to or greater-than the form cookie timeout. If you wish to store session out-of-process (on a remote system or in a database), configure accordingly.
Here are a few resources:
- Troubleshooting Expired ASPNET Session State
- Why would Asp.net mvc use session state
Storing it in your auth cookie can be forged, and it can expire as well. How about this - if you can make your session and auth cookie expire at the same time, would that work? If so, I can provide that solution to you easily. The code below checks if the session is not available, if so you are redirected to the login page. Change login.aspx below to whatever your login is. Also upon login you MUST set Session["UniqueUserId"] to be some value (could be anything.. just needs to be set to something)
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) { //Only access session state if it is available if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState) { //If we are authenticated AND we dont have a session here.. redirect to login page. HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authenticationCookie != null) { FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value); if (!authenticationTicket.Expired) { if (Session["UniqueUserId"] == null) { //This means for some reason the session expired before the authentication ticket. Force a login. FormsAuthentication.SignOut(); Response.Redirect("Login.aspx", true); return; } } } } }
精彩评论