我有一个使用MVC 5构建的应用程序,在这种情况下,即使用户仍在文本框中键入内容,但默认会话超时时间已过,仍将用户重定向到登录页面。我希望仅当页面闲置超过15分钟时才将用户重定向到登录页面,而不是在用户非常闲置时才重定向到登录页面。在Web表单中,我们用于在配置文件中将滑动过期设置为true,但这在MVC中不起作用。我将不胜感激。
这是我尝试过的:
[HttpPost]
[AllowAnonymous]
public ActionResult Login(LoginViewModel model, string returnUrl, string
command)
{
string decodedUrl = "";
if (!string.IsNullOrEmpty(returnUrl))
decodedUrl = Server.UrlDecode(returnUrl);
FormsAuthentication.SetAuthCookie(model.Email, false);
var authTicket = new FormsAuthenticationTicket(1, user.Email,
DateTime.Now, DateTime.Now.AddMinutes(15), false, user.Roles);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);
HttpContext.Response.Cookies.Add(authCookie);
authCookie.Expires = authTicket.Expiration;
if (Url.IsLocalUrl(decodedUrl))
{
return Redirect(decodedUrl);
}
else
{
return RedirectToAction("analytics", "dashboard");
}
}
全球ASAX代码:
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
try
{
var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
var roles = authTicket.UserData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
}
}
}
catch(Exception ex)
{
}
}
答案 0 :(得分:0)
您也可以使用javascript来实现。
// Set timeout variables.
var timoutWarning = 840000; // Display warning in 14 Mins.
var timoutNow = 900000; // Timeout in 15 mins.
var logoutUrl = '<url>'; // URL to logout page.
var warningTimer;
var timeoutTimer;
// Start timers.
function StartTimers() {
warningTimer = setTimeout("IdleWarning()", timoutWarning);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}
// Reset timers.
function ResetTimers() {
clearTimeout(warningTimer);
clearTimeout(timeoutTimer);
StartTimers();
$("#timeout").dialog('close');
}
// Show idle timeout warning dialog.
function IdleWarning() {
$("#timeout").dialog({
modal: true
});
}
// Logout the user.
function IdleTimeout() {
window.location = logoutUrl;
}
基本上将onload添加到调用StartTimers()的body标记中。您还可以在body标签上添加onmousemove,该标签调用ResetTimer(),以便只要页面上存在活动,就不会触发超时。如果在页面上没有看到鼠标活动,则在检测到移动时显示对话框,对话框将关闭并且计时器重置。 或者您也可以处理按键事件以重置计时器。
<body onload="StartTimers();" onmousemove="ResetTimers();">
您还可以从javascript调用MVC Action。
答案 1 :(得分:0)
如果cookie过期而没有对服务器发出任何请求,那么我认为您无能为力。在您的示例中,当用户在文本框中键入内容时被踢出门时,服务器如何知道他们正在这样做?
假设有 个请求正在服务器上运行,请在您的Application_PostAuthenticateRequest
处理程序中,仅检查是否有有效的现有故障单,剩余时间少于X
,如果是这样,则通过将其添加到响应中来发布新的。
遵循以下原则:
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
var roles = authTicket.UserData.Split(',');
var user = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
HttpContext.Current.User = user;
// Issue new ticket if there is less than 7 minutes remaining on current one.
if ((authTicket.Expires - DateTime.Now) <= TimeSpan.FromMinutes(7))
{
var authTicket = new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(15), false, user.Roles);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Response.Cookies.Add(authCookie);
}
}
}