Я ищу учебник, запись в блоге или некоторую помощь по технике веб-сайтов, которые автоматически подталкивают пользователей (т.е. без обратной передачи), когда сессия заканчивается. Любая помощь приветствуется
Перенаправление пересылки ASP.NET при тайм-ауте сеанса
Ответ 1
Обычно вы устанавливаете тайм-аут сеанса, и вы можете дополнительно добавить заголовок страницы, чтобы автоматически перенаправить текущую страницу на страницу, где вы очищаете сеанс непосредственно перед таймаутом сеанса.
От http://aspalliance.com/1621_Implementing_a_Session_Timeout_Page_in_ASPNET.2
namespace SessionExpirePage
{
public partial class Secure : System.Web.UI.MasterPage
{
public int SessionLengthMinutes
{
get { return Session.Timeout; }
}
public string SessionExpireDestinationUrl
{
get { return "/SessionExpired.aspx"; }
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.PageHead.Controls.Add(new LiteralControl(
String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
SessionLengthMinutes*60, SessionExpireDestinationUrl)));
}
}
}
SessionExpireDestinationUrl должен ссылаться на страницу, где вы очищаете сеанс и любые другие пользовательские данные.
Когда заголовок обновления заканчивается, он автоматически перенаправляет их на эту страницу.
Ответ 2
Вы не можете "нажать" клиента с вашего сайта. Ваш сайт будет отвечать на запросы от клиента, но это действительно так.
Это означает, что вам нужно написать что-то клиентское (Javascript), которое будет определять время ожидания пользователя, возможно, путем сравнения текущего времени с самым последним моментом, который у них есть в файле cookie сайта (который вы обновляете с текущим временем каждый раз, когда пользователь посещает страницу на вашем сайте), а затем перенаправлять, если разница больше определенной суммы.
(Я отмечаю, что некоторые люди выступают за создание script, который будет перенаправлять пользователя через определенное количество времени на странице. Это будет работать в простом случае, но если у пользователя есть два окна, сайт, и много использует одно окно, а в другом окне не так много, мало кто из них внезапно перенаправляет пользователя на страницу пересылки, даже если пользователь постоянно находится на этом сайте. Кроме того, он не синхронизируется с сеансом, который вы делаете на стороне сервера. С другой стороны, это, безусловно, проще для кодирования, и если это достаточно хорошо, тогда здорово!)
Ответ 3
В разделе <HEAD> используйте тег обновления META, например:
<meta http-equiv="refresh" content="0000; URL=target_page.html">
где 0000 - ваш тайм-аут сеанса в секундах, а target_page.html адрес страницы, на которую будет перенаправлен.
Ответ 4
Используя пользовательский класс страницы и Javascript, мы также можем его достичь.
Создайте собственный класс базы данных и напишите коды общей функциональности в этом классе. Благодаря этому классу мы можем использовать общие функции для других веб-страниц. В этом классе нам нужно наследовать класс System.Web.UI.Page. Поместите приведенный ниже код в класс Pagebase
PageBase.cs
namespace AutoRedirect
{
public class PageBase : System.Web.UI.Page
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
AutoRedirect();
}
public void AutoRedirect()
{
int int_MilliSecondsTimeOut = (this.Session.Timeout * 60000);
string str_Script = @"
<script type='text/javascript'>
intervalset = window.setInterval('Redirect()'," + int_MilliSecondsTimeOut.ToString() + @");
function Redirect()
{
window.location.href='/login.aspx';
}
</script>";
ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", str_Script);
}
}
}
Выше функция AutoRedirect будет использоваться для перенаправления страницы входа при завершении сеанса, с помощью javascript window.setInterval, This window.setInterval повторно выполняет функцию javascript с определенной задержкой по времени. Здесь мы настраиваем временную задержку как значение тайм-аута сеанса. После того, как он достиг времени окончания сеанса, он автоматически выполняет функцию перенаправления и управляет переносом на страницу входа.
OriginalPage.aspx.cs
namespace appStore
{
public partial class OriginalPage: Basepage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
OriginalPage.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OriginalPage.aspx.cs" Inherits="AutoRedirect.OriginalPage" %>
Web.config
<system.web>
<sessionState mode="InProc" timeout="3"></sessionState>
</system.web>
Примечание: Преимущество использования Javascript заключается в том, что вы можете отображать пользовательское сообщение в поле предупреждения до location.href, которое будет иметь для пользователя прекрасный смысл. Если вы не хотите использовать Javascript, вы можете выбрать мета перенаправление также
public void AutoRedirect()
{
this.Header.Controls.Add(new LiteralControl(
String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
this.Session.Timeout * 60, "login.aspx")));
}
Ответ 5
Просто скопируйте и вставьте этот фрагмент кода в файл Web.Config:
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" slidingExpiration="true" timeout="29" />
</authentication>
<sessionState timeout="30" mode="InProc" cookieless="false" />
Вы можете поместить эту строку на свой сайт. Мастера:
Response.AppendHeader("Refresh",
Convert.ToString((Session.Timeout * 60)) +
";URL=~/Login.aspx");
Ответ 6
Я использую MVC3 ASp.net как новичок, я пробовал много решений для решения моей проблемы с сеансом (поскольку я использую переменную Session в своем коде, и после таймаута у меня не было значений сеанса, пока я держусь используя его И я просто обнаружил, что моя проблема была в файле конфигурации. Тайм-аут между аутентификацией и sessionState должен быть настолько близок, чтобы они одновременно убивали (пусто)//добавляли таймаут 1 и 2 для тестирования.. он должен быть в не менее 29 и 30
Я использовал другие способы работы:
Начиная с:
protected void Session_Start(object src, EventArgs e)
{
if (Context.Session != null)
{
if (Context.Session.IsNewSession)//|| Context.Session.Count==0)
{
string sCookieHeader = Request.Headers["Cookie"];
if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
//if (Request.IsAuthenticated)
FormsAuthentication.SignOut();
Response.Redirect("/Account/LogOn");
}
}
}
}
protected void Session_End(object sender, EventArgs e)
{
//Code that runs when a session ends.
//Note: The Session_End event is raised only when the sessionstate mode
//is set to InProc in the Web.config file. If session mode is set to StateServer
//or SQLServer, the event is not raised.
Session.Clear();
}
И:
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
ctx.Response.Redirect("~/Home/LogOn");
}
}
}
base.OnActionExecuting(filterContext);
}
}
И даже работал с Ajax для решения сеанса issuse:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Session.Count == 0 || Session["CouncilID"] == null)
Response.Redirect("/Account/LogOn");
if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
{
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
}
else
{
base.OnActionExecuting(filterContext);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAjaxRequest())
{//validate http request.
if (!httpContext.Request.IsAuthenticated
|| httpContext.Session["User"] == null)
{
FormsAuthentication.SignOut();
httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
return false;
}
}
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new
{
// put whatever data you want which will be sent
// to the client
message = "sorry, but you were logged out"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
Ответ 7
К сожалению, это невозможно. Тайм-аут сеанса возникает только на стороне сервера, и вы не обнаружите его до тех пор, пока пользователь не выполнит какое-либо действие обратной обратной связи.
Однако, что вы МОЖЕТЕ сделать, это ввести код HTML или JavaScript, который автоматически выведет пользователя на страницу выхода в тот же таймфрейм, что и таймаут сеанса. Это не гарантирует идеальную синхронизацию, и вы можете столкнуться с проблемами, если ваш пользователь выполняет некоторые интенсивные элементы времени, и вы не перезагружаете часы.
Обычно я добавляю этот код в мои события Page_Load, чтобы выполнить это.
' Register Javascript timeout event to redirect to the login page after inactivity
Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", _
"setTimeout(""top.location.href = 'Login.aspx'""," & _
ConfigurationManager.AppSettings("SessionTimeoutMilliseconds") & ");", True)
Ответ 8
Конечно, вам нужно использовать [Authorize]
над классом контроллера или даже Action в специфическом.
[Authorize]
public class MailController : Controller
{
}
Ответ 9
И если вы используете следующий контроллер входа в систему, он отправит вас на запрошенный URL-адрес перед входом в систему:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
//return Redirect(returnUrl);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Ответ 10
Ну, это сложно сделать для запросов AJAX, как отметил Жаф - Бен Дугид. Вот мое решение, чтобы сделать эту работу с AJAX (используя веб-элементы Telerik, но они построены с использованием инструментария ASP.NET AJAX, который я считаю).
Вкратце, я перевернул свою собственную тему сеанса сеанса скольжения.
В моем Site.Master я обновляю переменную сеанса в КАЖДОМ обратном обратном письме (postback или AJAX-запрос, поскольку запросы AJAX по-прежнему запускают событие Page_Load):
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
if (this.Request.IsAuthenticated)
this.pnlSessionKeepAlive.Visible = true;
else
this.pnlSessionKeepAlive.Visible = false;
}
if (this.Session["SessionStartDateTime"] != null)
this.Session["SessionStartDateTime"] = DateTime.Now;
else
this.Session.Add("SessionStartDateTime", DateTime.Now);
}
Затем в моей разметке для моего сайта .master я включил iframe с ASPX-страницей, которую я использую "за кулисами", чтобы проверить, истекло ли мое пользовательское истечение срока действия:
<asp:Panel runat="server" ID="pnlSessionKeepAlive" Visible="false">
<iframe id="frame1" runat="server" src="../SessionExpire.aspx" frameborder="0" width="0" height="0" / >
</asp:Panel>
Теперь на моей странице SessionExpire.aspx я просто обновляю страницу так часто и проверяю, продлилась ли временная метка, и если да, я перенаправляюсь на мою страницу logout.aspx, которая затем определяет, какую страницу входа отправить пользователю обратно
public partial class SessionExpire : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
/* We have to do all of this because we need to redirect to 2 different login pages. The default .NET
* implementation does not allow us to specify which page to redirect expired sessions, its a fixed value.
*/
if (this.Session["SessionStartDateTime"] != null)
{
DateTime StartTime = new DateTime();
bool IsValid = DateTime.TryParse(this.Session["SessionStartDateTime"].ToString(), out StartTime);
if (IsValid)
{
int MaxSessionTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionKeepAliveMins"]);
IsValid = (DateTime.Now.Subtract(StartTime).TotalMinutes < MaxSessionTimeout);
}
// either their session expired or their sliding session timeout has expired. Now log them out and redirect to the correct
// login page.
if (!IsValid)
this.Logout();
}
else
this.Logout();
// check every 60 seconds to see if the session has expired yet.
Response.AddHeader("Refresh", Convert.ToString(60));
}
private void Logout()
{
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "TimeoutScript",
"setTimeout(\"top.location.href = '../Public/Logout.aspx'\",\"1000\");", true);
}
}
Большое спасибо людям выше, кто разместил информацию, это привело меня к моему решению и надеюсь, что это поможет другим.