gpt4 book ai didi

asp.net - 在 asp.net 中 session 超时时通知用户

转载 作者:行者123 更新时间:2023-12-03 18:21:16 25 4
gpt4 key购买 nike

session 过期后向用户显示消息的最佳方式是什么?
到那时,用户应该被注销并被重定向到起始页面。
我可以使用 javascript 将用户重定向到起始页面。我只想在开始页面上显示一条消息。

最佳答案

此答案的先前版本包含一些简单的来源,用于解决不再存在的问题。

场景是他想收到通知之前 session 超时,以便可以采取行动。

目前尚不清楚它是 asp.net session 还是表单例份验证票,但确实是同一个问题。

基本上相当于异步 session 状态管理,而不触发 session /票证续订。 ajax 应用程序的共同愿望。

解决方案非常简单,但并不完全直截了当。有很多问题需要处理,但我提出了一个对简单 session 状态和表单例份验证都可靠的解决方案。

它由一个非常轻量级的 httpmodule 和随附的客户端脚本库组成,有效的代码行数也不多于 50 或 60 行。

该策略是提供一个 http 端点,该端点可以查询 session 的到期状态或形成票证,而无需更新它们。该模块只是位于管道的前面,并为几个“虚拟”端点提供 javascript 日期和一个非常简单的 js lib 来进行调用。

演示和源代码在这里:AsynchronousSessionAuditor

你们中的一些人想知道为什么我会关心这个,但可能你们中的更多人会说,是的,是的,这太痛苦了。我知道我过去曾提出过易碎的臭味解决方法,对此我感到非常满意。

它可以在标准回发模型应用程序或更可能是 ajax 应用程序中提供服务。
还...
您可以了解更多关于 Http 请求生命周期的信息 herehere .如果有兴趣,请了解更多关于在 asp.net 端点上使用原始 xmlhttp here

删除以前的尖峰代码。如果您有兴趣,请查看修订历史。

以下是相关的源文件。完整的引用实现可从上面提供的链接获得......

HttpModule

// <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditorModule.cs" company="Sky Sanders">
// This source is a Public Domain Dedication.
// http://spikes.codeplex.com
// Attribution is appreciated.
// </copyright>

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace Salient.Web.Security
{
/// <summary>
/// AsynchronousSessionAuditorModule provides a mechanism for auditing the lifecycle
/// of an ASP.Net session and/or an ASP.Net FormsAuthentication cookie in the interest
/// of providing better monitoring and control of a user session. This is becoming more
/// important as more and more web apps are single page apps that may not cycle a page for
/// many minutes or hours.
///
/// Storing a token in the Asp.net Session was for many years the default authentication strategy.
/// The are still valid applications for this techique although FormsAuthentication has far
/// surpassed in security and functionality.
///
/// What I am providing is a manner in which to transparently monitor the expiration status of each
/// by implementing a module that recognizes two virtual endpoints:
///
/// http://mysite/.aspnetsession
/// http://mysite/.formsauthticket
///
/// By making a request to these urls you will be delivered a javascript date in numeric form that
/// represents the expiration dateTime of either the current ASP.Net session, if any, or the current
/// FormsAuthentication ticket expiration, if any.
///
/// If the requested item does not exists, zero is returned. Any value served by this module should
/// be cast to a date and compared with Now. If less than you should take action. You should have
/// taken action on the client before the session timed out, aided by the output of this module, but
/// hey, nobody is perfect.
/// </summary>
public class AsynchronousSessionAuditorModule : IHttpModule
{
// note: these must remain in sync with the string keys in the javascript
private const string AspSessionAuditKey = ".aspnetsession";

private const string FormsAuthAuditKey = ".formsauthticket";

#region IHttpModule Members

public void Init(HttpApplication context)
{
// this is our audit hook. get the request before anyone else does
// and if it is for us handle it and end. no one is the wiser.
// otherwise just let it pass...
context.BeginRequest += HandleAuditRequest;

// this is as early as we can access session.
// it is also the latest we can get in, as the script handler is coming
// right after and we want to beat the script handler to the request
// will have to set a cookie for the next audit request to read in Begin request.
// the cookie is used nowhere else.
context.PostAcquireRequestState += SetAuditBugs;
}

public void Dispose()
{
}

#endregion

private static void SetAuditBugs(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;

if ((app.Context.Handler is IRequiresSessionState || app.Context.Handler is IReadOnlySessionState))
{
HttpCookie sessionTimeoutCookie = new HttpCookie(AspSessionAuditKey);

// check to see if there is a session cookie
string cookieHeader = app.Context.Request.Headers["Cookie"];
if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0) &&
!app.Context.Session.IsNewSession)
{
// session is live and this is a request so lets ensure the life span
app.Context.Session["__________SessionKicker"] = DateTime.Now;
sessionTimeoutCookie.Expires = DateTime.Now.AddMinutes(app.Session.Timeout).AddSeconds(2);
sessionTimeoutCookie.Value = MilliTimeStamp(sessionTimeoutCookie.Expires).ToString();
}
else
{
// session has timed out; don't fiddle with it
sessionTimeoutCookie.Expires = DateTime.Now.AddDays(-30);
sessionTimeoutCookie.Value = 0.ToString();
}
app.Response.Cookies.Add(sessionTimeoutCookie);
}
}

private static void HandleAuditRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication) sender).Context;
bool formsAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + FormsAuthAuditKey);
bool aspSessionAudit = context.Request.Url.PathAndQuery.ToLower().StartsWith("/" + AspSessionAuditKey);

if (!formsAudit && !aspSessionAudit)
{
// your are not the droids i am looking for, you may move along...
return;
}

double timeout;
// want to know forms auth status
if (formsAudit)
{
HttpCookie formsAuthCookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (formsAuthCookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsAuthCookie.Value);
timeout = MilliTimeStamp(ticket.Expiration);
}
else
{
timeout = 0;
}
}
// want to know session status
else
{
// no session here, just take the word of SetAuditBugs
HttpCookie sessionTimeoutCookie = context.Request.Cookies[AspSessionAuditKey];
timeout = sessionTimeoutCookie == null ? 0 : Convert.ToDouble(sessionTimeoutCookie.Value);
}

// ensure that the response is not cached. That would defeat the whole purpose
context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
// the money shot. a javascript date.
context.Response.Write(timeout.ToString());
context.Response.Flush();
context.Response.End();
}

/// <summary>
/// Found Code: http://forums.asp.net/t/1044408.aspx
/// </summary>
/// <param name="TheDate"></param>
/// <returns></returns>
private static double MilliTimeStamp(DateTime TheDate)
{
DateTime d1 = new DateTime(1970, 1, 1);
DateTime d2 = TheDate.ToUniversalTime();
TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks);

return ts.TotalMilliseconds;
}
}
}

客户图书馆
// <copyright project="AsynchronousSessionAuditor" file="AsynchronousSessionAuditor.js" company="Sky Sanders">
// This source is a Public Domain Dedication.
// http://spikes.codeplex.com
// Attribution is appreciated.
// </copyright>


var AsynchronousSessionAuditor = {
/// this script really should be served as a resource embedded in the assembly of the module
/// especially to keep the keys syncronized

pollingInterval: 60000, // 60 second polling. Not horrible, except for the server logs. ;)

formsAuthAuditKey: ".formsauthticket", // convenience members
aspSessionAuditKey: ".aspnetsession",

errorCallback: function(key, xhr) {
/// <summary>
/// Default behavior is to redirect to Default and provide the xhr error status text
/// in the loggedout query param.
///
/// You may replace this default behaviour with your own handler.
/// e.g. AsynchronousSessionAuditor.errorCallback = myMethod;
/// </summary>
/// <param name="key" type="String"></param>
/// <param name="xhr" type="XMLHttpRequest"></param>
window.location = "Default.aspx?loggedout=Error+" + xhr.statusText;
},

timeoutCallback: function(key, xhr) {
/// <summary>
/// Default behavior is to redirect to Default and provide the key value
/// in the loggedout query param.
///
/// You may replace this default behaviour with your own handler.
/// e.g. AsynchronousSessionAuditor.timeoutCallback= myMethod;
/// </summary>
/// <param name="key" type="String"></param>
/// <param name="xhr" type="XMLHttpRequest"></param>
window.location = "Default.aspx?loggedout=" + key;
// or just refresh. you will be sent to login.aspx
},

statusCallback: function(value) {
/// <summary>
/// Default behavior is to do nothing, which is not very interesting.
/// This value is set when AsynchronousSessionAuditor.init is called
/// </summary>
/// <param name="value" type="String">
/// The responseText of the audit request. Most certainly is a JavaScript Date
/// as a number. Just cast to date to get the requested expiration dateTime.
/// e.g. var exp = new Date(parseFloat(value)); if (isNaN(exp)){this should never happen}
/// </param>

window.location = "Default.aspx?loggedout=" + key;
// or just refresh. you will be sent to login.aspx
},

createXHR: function() {
/// <summary>
/// This xhr factory is not the best I have see.
/// You may wish to replace it with another or
/// use your favorite ajax library to make the
/// call.
/// </summary>
var xhr;

if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
else {
throw new Error("Could not create XMLHttpRequest object.");
}
return xhr;
},


auditSession: function(key) {
/// <summary>
/// Make a request that will be serviced by the audit module to determine the
/// state of the current FormsAuthentication ticket or Asp.Net session
///
/// The return value is a JavaScript date, in numeric form, that represents the
/// expiration of the item specified by key.
/// Just cast it to date, i.e. new Date(parseFloat(xhr.resposeText))
/// </summary>
/// <param name="key" type="String">
/// the server key for the item to audit.
///
/// use ".formsauthticket" to get the expiration dateTime for the forms authentication
/// ticket, if any.
///
/// use ".aspnetsession" to get the expiration of the current ASP.Net session.
///
/// Both have convenience members on this object.
/// </param>

var xhr = AsynchronousSessionAuditor.createXHR();

xhr.open("GET", key, true);

xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status != 200) {
AsynchronousSessionAuditor.errorCallback(key, xhr);
}
else {

var timeout = parseFloat(xhr.responseText)
if (isNaN(timeout) || (new Date(timeout) < new Date())) {
AsynchronousSessionAuditor.timeoutCallback(key, xhr);
}
else {
AsynchronousSessionAuditor.statusCallback(xhr.responseText);
}
}

}
};
xhr.send(null);
},

init: function(key, statusCallback) {
// set the statusCallback member for reference.
AsynchronousSessionAuditor.statusCallback = statusCallback;
// check right now
AsynchronousSessionAuditor.auditSession(key);
// and recurring
window.setInterval((function() { AsynchronousSessionAuditor.auditSession(key) }), AsynchronousSessionAuditor.pollingInterval);
}
};



function callScriptMethod(url) {
/// <summary>
///
/// Simply makes a bogus ScriptService call to a void PageMethod name DoSomething simulating
/// an async (Ajax) call.
/// This resets the session cookie in the same way a postback or refresh would.
///
/// The same would apply to a ScriptService enabled XML Webservice call.
/// </summary>

var xhr = AsynchronousSessionAuditor.createXHR();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status != 200) {
alert("script method call failed:" + xhr.statusText);
}
}
};
xhr.setRequestHeader("content-type", "application/json");
var postData = null;
xhr.send(postData);
}

用法
<script src="AsynchronousSessionAuditor.js" type="text/javascript"></script>

<script type="text/javascript">

function reportStatus(value) {
/// <summary>
/// In a typical session/ticket lifetime you might display a warning at T-5 minutes that the session
/// is expiring and require an action.
/// </summary>

document.getElementById("sessionTimeout").innerHTML = "Session expires in " + parseInt((new Date(parseFloat(value)) - new Date()) / 1000) + " seconds.";
}

function init() {

// default is 60 seconds. Our session is only 1 minute so lets get crazy and poll every second
AsynchronousSessionAuditor.pollingInterval = 1000;
AsynchronousSessionAuditor.init(AsynchronousSessionAuditor.aspSessionAuditKey, reportStatus);
}

</script>

关于asp.net - 在 asp.net 中 session 超时时通知用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2234348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com