我有一个asp.net网站使用表单认证。我在会话中保留了一些用户名,用户ID,电子邮件等。
我允许用户通过在身份验证Cookie上设置较长的到期日期来保持登录网站。因此,在用户仍然通过身份验证时,会话过期是非常常见的。
我遇到的问题是,有时用户的会话超时,但他们仍然进行身份验证。因此,例如,我的一个用户页面(需要身份验证)会在他们的会话处于活动状态时说“欢迎麦克”,但一旦到期,它会说“欢迎[空白]”,因为该信息不再在会话中,仍然被认证。
什么是最好的办法来处理这个?当信息不再存在时,我应该重新同步会话信息吗?或者我应该将用户信息(用户名,用户ID,电子邮件)移动到cookies,不担心会话超时?
解决方法
避免使用会话尽可能多,如果你可以逃避没有看到它使多服务器部署qutie有点更容易。很可能,姓名和电子邮件是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); }
FYI,我从一个旧项目复制,并在这里编辑它删除一些项目特定的位,所以它可能无法编译,但它会非常接近。
要在您的网页中获取ID …
FormsAuthenticationTicket ticket = ((FormsIdentity) Page.User.Identity).Ticket; string id = ticket.UserData;
我使用这种机制来存储不是aspnetdb用户数据的一部分的id。如果所有的身份数据都由aspnetdb处理,您可能只需要访问Page.User.Identity对象。