我有一个Asp.net Web应用程序,我使用FormsAuthentication进行用户登录。
我想防止同时多次登录同一个用户。为此,我将FormsAuthentication超时设置为15分钟,将Session.timeout设置为15分钟。
当用户在没有注销的情况下关闭浏览器,或者用户处于非活动状态15分钟时,它不会在global.asax.cs文件中触发Session_End()事件。我想更新Session_End()事件中的数据库字段。
登录代码:
if (Membership.ValidateUser(username, password))
{
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(15),
false,
FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1"));
// Now encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
context.Response.Cookies.Add(authCookie);
context.Response.Redirect("/HomePage", false);
}
的Global.asax.cs:
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
Session.Timeout = 15;
}
protected void Session_End(Object sender, EventArgs e)
{
PersonObject person = new PersonObject();
// calling the function to update entry in database
person.ResetUserLoginStatus(HttpContext.Current.User.Identity.Name);
}
更新数据库中的条目的功能:
public bool ResetUserLoginStatus( string username="")
{
string sql = "UPDATE Person SET IsLogged=0 WHERE Person = @Person";
PersonObject person = new PersonObject();
object id = person.ExecuteScalar(sql, new Dictionary<string, object>() {
{ "Person", (!string.IsNullOrEmpty(username)?username:User.Name )}
}, "Person");
return true;
}
Web.config文件:
<authentication mode="Forms">
<forms loginUrl="/Security/Login.ashx/Home" name="SecurityCookie" timeout="15" slidingExpiration="true">
</forms>
</authentication>
<sessionState timeout="15" mode="InProc"></sessionState>
问题是当浏览器关闭时,不调用ResetUserLoginStatus()方法,我无法将我的值重置为0.由于该字段尚未重置为0,该用户将无法再次登录。
请建议。
Session_End实际上没那么有用或可靠。首先,它仅在收到HTTP请求并且已呈现响应时在管道处理结束时触发。这意味着它不会为只是关闭浏览器的用户触发。此外,除了某些类型的会话状态外,事件永远不会触发 - 例如,它不适用于State Server或基于SQL的会话状态。底线是你不能依赖它来维持一个明确的“登录”标志。
相反,我会存储“收到最后一页请求”的时间戳。然后,您可以推断出“已登录”标志的值;在过去15分钟内提交请求的任何用户仍然登录。