我有一个使用窗体身份验证的ASP.NET网站.我在会话中保留了一些内容,比如用户名、用户名、邮箱等等.

我允许用户通过在认证cookie上设置一个很长的过期日期来保持登录该网站.因此,当用户仍在进行身份验证时,会话过期是很常见的.

我遇到的问题是,有时用户的会话超时,但它们仍然经过身份验证.例如,我的一个用户页面(需要身份验证)在会话处于活动状态时会说"Welcome Mike",但一旦会话过期,它会说"Welcome[blank]",因为该信息已不在会话中,但它们仍然经过身份验证.

最好的处理方法是什么?当信息不再存在时,我是否应该重新同步会话信息?或者我应该将用户信息(用户名、用户ID、邮箱)移动到cookie中,而不必担心会话超时?

我不想将会话长度设置为60分钟或更长.What i want is for my users to be able to login once and not worry about having to login again until they explicitly logout.

推荐答案

尽量避免使用Session,如果您可以在不使用Seed的情况下离开,这将使多服务器部署变得更容易一些.很可能,姓名和邮箱很容易成为cookie的候选对象.伪造cookie很容易,因此根据您的安全需要,userid可能不是一个好主意.

表单验证cookie是加密的,您可以向这些cookie中添加额外的数据(请参阅下面的详细信息).它可能是可以破解的,但不像一个简单的cookies 那么容易.

下面是我在过go 使用的代码,这些代码经过了轻微修改,删除了一些特定于项目的细节.在登录控件的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处理,则您可能只需要访问该页面.使用者标识对象.

Asp.net相关问答推荐

ASP.NET 核心中的 Request.CreateResponse

你能从请求变量中确定时区吗?

如何从网页 (asp.net) 启动 EXE

如何在 ASP.NET core rc2 中禁用浏览器缓存?

相当于服务器端的 ASP.NET 包括

在每个控制器的 ASP.NET WebAPI 上强制使用 CamelCase

在 ASP.NET Core 1.0 上处理大文件上传

带有邮箱地址参数的 WebApi 方法从 HttpClient 返回 404

如何从 HTTP 请求中获取 MAC 地址?

如何以编程方式将标签的前景色设置为其默认值?

Page.IsValid 是如何工作的?

用于验证的数据注释,至少一个必填字段?

根据 DropDownList 的值动态启用或禁用RequiredFieldValidator

将 C# ASP.NET 数组传递给 Javascript 数组

ASP.NET 中的嵌套中继器

如何判断字符串的第一个字符是否是字母,C#中的任何字母

ASP.net 判断页面是 http 还是 https

强制 IIS Express 进入classic 管道模式

如何使 URL 重写与 web.Release.config 转换一起工作?

System.Drawing.Image.FromFile() 上的内存不足异常