我有一个使用表单身份验证的asp.net网站.我在会话中保留了一些内容,如用户名,用户ID,电子邮件等.
我允许用户通过在身份验证cookie上设置较长的到期日期来保持登录网站.因此,当用户仍然进行身份验证时,会话过期是很常见的.
我遇到的问题是,有时用户的会话超时但他们仍然经过身份验证.因此,例如,我的一个用户页面(需要身份验证)会在其会话处于活动状态时说"欢迎Mike",但一旦过期,它将显示"Welcome [blank]",因为该信息不再在会话中,但他们仍然经过身份验证.
处理这个问题的最佳方法是什么?当信息不再存在时,我应该重新同步会话信息吗?或者我应该将用户信息(用户名,用户ID,电子邮件)移动到cookie中而不用担心会话超时?
我不想将会话长度设置为60分钟或更长时间.我想要的是我的用户能够登录一次而不用担心必须再次登录才能明确注销.
避免尽可能多地使用会话,如果你可以在没有看到的情况下离开,它会使多服务器部署更容易.也许,姓名和电子邮件很容易成为cookie的候选者.伪造一个cookie很容易,因此根据您的安全需求,userID可能不是一个好主意.
表单身份验证cookie已加密,您可以向这些cookie添加额外数据(请参阅下面的详细信息).它可能是可以破解的,但不像简单的cookie那么容易.
这是我过去使用过的代码稍加修改以删除一些项目特定的细节.在登录控件的LoggedIn事件中调用它.
void AddUserIDToAuthCookie(string userID) { //There is no way to directly set the userdata portion of a FormAuthenticationTicket //without re-writing the login portion of the Login control // //I find it easier to pull the cookie that the Login control inserted out //and create a new cookie with the userdata set HttpCookie authCookie = Response.Cookies[AUTH_COOKIE]; if(authCookie == null) { return; } Response.Cookies.Remove(AUTH_COOKIE); FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(authCookie.Value); var newTicket = new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, oldTicket.IssueDate, oldTicket.Expiration, oldTicket.IsPersistent, userID, oldTicket.CookiePath); authCookie.Value = FormsAuthentication.Encrypt(newTicket); Response.Cookies.Add(authCookie); }
仅供参考,我从一个旧项目复制了这个并在这里编辑它以删除一些项目特定的位,因此它可能无法编译,但它将非常接近.
要在您的网页中获取ID ...
FormsAuthenticationTicket ticket = ((FormsIdentity) Page.User.Identity).Ticket; string id = ticket.UserData;
我使用这种机制来存储不属于aspnetdb用户数据的id.如果所有身份数据都由aspnetdb处理,则可能只需要访问Page.User.Identity对象.