如何使用FormsAuthentication保存内容?我不想通过URL存储UserId。
例如,现在我有这个代码:
//UserController class: [HttpPost] public ActionResult logon(logonModel model,string returnUrl) { if (ModelState.IsValid) { if (repository.ValidateUser(model.Login,model.Password)) { FormsAuthentication.SetAuthCookie(model.Login,model.RememberMe); if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Project","Index"); } } else { ModelState.AddModelError("","Incorrect name or password."); } } return View(model); }
ProjectController类:
public ViewResult Index() { return View(repository.GetUserProjects( this.ControllerContext.HttpContext.User.Identity.Name)); }
ProjectRepository:
ProjectsContext context = new ProjectsContext(); UsersContext uCnt = new UsersContext(); public IEnumerable<Project> GetUserProjects(String username) { if (String.IsNullOrEmpty(username)) throw new ArgumentNullException("username","Login is empty"); return this.uCnt.Users .FirstOrDefault(u => u.Login == username) .Projects .ToList(); }
ProjectController和ProjectRepository看起来不是很好的代码…也许有人可以提供建议,如何存储UserID而不使用URL?我认为最好的方法是保存自动识别ID。我没有在User.Identity中找到任何属性来执行此操作
UPD
我乞求赦免,但我忘了说我在使用MVC-3与剃须刀视图。
而UserId不是一个字符串(User.Identity.Name是一个字符串),它可以是GUID或也许我自己的对象…
解决方法
当用户登录时,将UserID保存在授权cookie中的FormsAuthentication故障单的UserData属性中:
string userData = userID.ToString(); FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,user.Email,DateTime.Now,DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),createPersistentCookie,userData); string hashedTicket = FormsAuthentication.Encrypt(ticket); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,hashedTicket); HttpContext.Current.Response.Cookies.Add(cookie);
您可以在Global.asax中的PostAuthenticateRequest方法中阅读:
HttpCookie formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (formsCookie != null) { FormsAuthenticationTicket auth = FormsAuthentication.Decrypt(formsCookie.Value); Guid userID = new Guid(auth.UserData); var principal = new CustomPrincipal(Roles.Provider.Name,new GenericIdentity(auth.Name),userID); Context.User = Thread.CurrentPrincipal = principal; }
请注意,在这种情况下,CustomPrincipal派生自RolePrincipal(虽然如果您不使用Roles,我认为您需要从GenericPrincipal派生),并且只需添加UserID属性并重构构造函数。
现在,无论您在应用中需要UserID,您都可以这样做:
if(HttpContext.Current.Request.IsAuthenticated) Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;