我很难弄清楚这一点。我正在使用表单例份验证。当用户登录并检查记住我时,我希望用户保持登录状态 24 小时。问题是,无论我做什么,用户都会在 30 分钟后自动注销。我们用户选择记住我,我设置了一个持久 cookie,在 24 小时后过期。我可以在浏览器选项中看到 cookie,并且过期时间是正确的。如果我离开网站并在一个小时内返回。用户已注销……他是我所拥有的一些代码片段。
bool IsValid = Membership.ValidateUser(LoginControl.UserName, LoginControl.Password);
if (IsValid)
{
e.Authenticated = true;
if (LoginControl.RememberMeSet)
{
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(LoginControl.UserName, true, 1440); // 1 day
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.Expires = authTicket.Expiration;
HttpContext.Current.Response.Cookies.Set(cookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(LoginControl.UserName, true), true);
FormsAuthentication.SetAuthCookie(LoginControl.UserName, true);
FormsAuthentication.RedirectFromLoginPage(LoginControl.UserName, true);
}
else
{
FormsAuthentication.SetAuthCookie(LoginControl.UserName, false);
FormsAuthentication.RedirectFromLoginPage(LoginControl.UserName, false);
}
}
这是我的 web.config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" defaultUrl="/" timeout="1" cookieless="UseCookies" protection="All" slidingExpiration="true" ticketCompatibilityMode="Framework40"/>
</authentication>
当用户没有检查“记住我”时,我会设置一个非持久性 cookie,并在 1 分钟不活动后用户注销。这是正常工作的。问题是,当设置了记住 cookie 并且用户返回时,即使有 cookie,用户也不再登录。
最佳答案
在 web.config 中设置以下 session 状态超时。默认情况下, session 超时为 20 分钟。
<system.web>
...
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="1440" />
</authentication>
...
<sessionState timeout="1440"/>
...
</system.web>
解决方案
如果用户检查记住我,则使用默认票证设置设置身份验证 cookie。否则,请自行创建AuthenticationTicket。
string username = LoginControl.UserName;
if (LoginControl.RememberMeSet)
{
FormsAuthentication.SetAuthCookie(username, true);
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
var authTicket = new FormsAuthenticationTicket(username, true, 1);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket)
{
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
Path = FormsAuthentication.FormsCookiePath,
Domain = FormsAuthentication.CookieDomain,
Expires = authTicket.Expiration
};
Response.Cookies.Set(cookie);
// ***** Here is the fix *****
// Do not use FormsAuthentication.SetAuthCookie or RedirectFromLoginPage
// if you create own FormsAuthenticationTicket.
Response.Redirect("~/default.aspx");
}
测试
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
var sb = new StringBuilder();
var id = (FormsIdentity) User.Identity;
var ticket = id.Ticket;
sb.Append("Authenticated");
sb.Append("<br/>CookiePath: " + ticket.CookiePath);
sb.Append("<br/>Expiration: " + ticket.Expiration);
sb.Append("<br/>Expired: " + ticket.Expired);
sb.Append("<br/>IsPersistent: " + ticket.IsPersistent);
sb.Append("<br/>IssueDate: " + ticket.IssueDate);
sb.Append("<br/>Name: " + ticket.Name);
sb.Append("<br/>UserData: " + ticket.UserData);
sb.Append("<br/>Version: " + ticket.Version);
Label1.Text = sb.ToString();
}
else
Label1.Text = "Not Authenticated";
}
老实说, session 和身份验证 Cookie 超时 1 分钟太短了,但这取决于您。
此外,请在 web.config 中注明您自己创建 AuthenticationTicket。下一个调试您代码的人一定会欣赏它。
问题(已更新)
如果我们自己创建 FormsAuthenticationTicket ,我们不应该使用 FormsAuthentication.RedirectFromLoginPage ,它会覆盖我们的自定义过期日期并使用 web.config 中的过期日期。
关于asp.net - 保持用户登录状态 - FormsAuthentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16364858/