この機能を導入する目的は、とき紛争責任を駅員、他のスタッフ誤動作を離れるときにログアウトし忘れを防止するために、非常に簡単です。
まず、この記事の下の参考資料:
どのように、フレームワークは、Asp.Netそれぞれの仕事をされて処理するHTTP要求が、どのように、異なる要求間IIS、フレームワーク、Asp.Net 3つのフローの間でどのようにデータを区別するために、IIS?
一般ISAPIアプリケーション(インターネットサーバーアプリケーションProgrameインターフェイス、インターネットサーバーアプリケーションプログラミングインタフェース)として知られている様々なアプリケーション拡張、扱うことのできる
Asp.Netのみサーバー(IIS)は、それの不可欠な部分であり、それはISAPI拡張です。
httpRuntime Asp.NetクラスはHttpWorkerRequestクラスにパラメータとしてのprocessRequestと呼ばれる方法で、この方法を持っているメインエントランス、です。:ほとんどのhttpRuntimeクラスは、単一のHTTPリクエストに関するすべての情報が含まれ
要求されたファイル、サーバー変数、のQueryString、HTTPヘッダー情報などを。
Web.configファイルの内容が変更されたか、.aspxファイルが変更され、同じプロセス・アプリケーション(もリロードするアンインストール)で実行してアンロードすることができるようにするためには、HTTP要求が孤立アプリケーションドメインに分割されている場合にはインチ
IISの場合は、HTTP.SYSは、外部からのHTTP要求をリッスンするために、内蔵ドライバと呼ばれる依存しています。オペレーティングシステムが起動すると、最初のHTTP.SYSに自分の仮想パスを登録するIIS。
HTTPリクエストAsp.Netランタイムを入力するときは、その管理モジュールによってパイプライン(注:管理モジュール)とハンドラ(注:ハンドラ)は、組成物、およびパイプラインによって、HTTPリクエストを処理します。
一般来说,我们可以将Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。
而 Http Module 的作用是与应用程序事件 密切相关的。
Asp.Net 内置的 Http Modules
整个过程如下:
-
当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。
-
在创建Module实例的时候会调用Module的Init()方法。
-
在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。
-
HttpApplication在其应用程序周期中触发各类事件。
-
触发事件的时候调用Module在其Init()方法中注册过的方法。
2. HttpModule模块作用之三通过Session判断用户是否登陆
3. 判断Session过期
上述两个参考文档是可以直接参考的代码,非原理性讲解。
4. 利用HttpModule开发asp.net页面、ashx等访问时session失效的统一处理入口
HttpApplication处理事件的先后顺序,不同事件会处理不同的事情,需要注意使用顺序。
5. ASP.NET三剑客 HttpApplication HttpModule HttpHandler 解析
详细介绍了上述博客提到的HttpApplication、HttpModule、HttpHandler等对象
上面介绍的方法都是通过HttpModule判断session是否失效来决定是否返回登陆页面。
那么什么是Session,怎么设定Session的存续事件,集群环境下Session如何处理?这些问题的答案可以参考6-8这3篇博客。
经过上面的参考文档,我们的代码如下:
public class ModuleBackLogin : IHttpModule { public ModuleBackLogin() { // // TODO: 在此处添加构造函数逻辑 // } // Init方法仅用于给期望的事件注册方法 public void Init(HttpApplication context) { context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); } // 处理context_PreRequestHandlerExecute事件的实际代码 void context_PreRequestHandlerExecute(object sender, EventArgs e) { try { HttpApplication ha = (HttpApplication)sender;//获得发生该事件的对象 string path = ha.Context.Request.Url.ToString();//获得请求的url路径 int n = path.IndexOf("Login.aspx"); //判断是否是登陆页面 int m = path.IndexOf("LoginHandler.ashx"); //不是登录页面,也不是登录操作 if (n < 0 && m < 0) { if (ha.Context.Session != null) { if (ha.Context.Session[KeyConst.UserId] == null) { ha.Response.Write("<script>alert('登陆超时或者非法登录,请重新登录!!');top.window.location.href='Login.aspx';</script>"); ha.Response.End(); } } } } catch { } } public void Dispose() { } }
<?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/> <!--<httpModules> <add name="MyModule" type="ModuleBackLogin" /> </httpModules>--> <sessionState mode="InProc" timeout="10"/> <!--<httpRuntime requestValidationMode="2.0" />--> <pages validateRequest="false"></pages> </system.web> <system.webServer> <modules> <add name="MyModule" type="ModuleBackLogin" /> </modules> </system.webServer> </configuration>
上述的参考文档及代码是使用ASP.NET及Session判断网页过期及强制重新登录。
下一个项目我们使用的是ASP.NET MVC,那么这个要怎么处理呢?上述解决方案还有一个隐藏问题,如果请求页面是OK的,但是如果是AJAX请求,那么页面会报错,但是并不会强制重新登录,这个问题要怎么解决呢?请继续往下阅读~
参考资料如下:
1. Asp.net MVC使用Filter解除Session, Cookie等依赖
filter的简单介绍。
MVC对HTTP请求的处理和ASP.NET有些不一样,比如MVC是通过给Controller加Filter,ASP.NET是通过HttpModule。
该文章介绍了使用Filter进行session过期的判断。
也解决了前文我提到的一个问题,AJAX请求失败的问题。
但是文章还有个问题待解决,难道要在网页上所有的ajax请求处都要加以处理?
当授权过期后,针对ajax请求返回一个特定的标识,然后前端通过识别该标识,来跳转到登录页面。而且最好不用在每处ajax请求的代码中都加上对这种标识判断,即要能全局处理。
所以目标就落在了jQuery.ajax的全局配置($.ajaxSetup)上了,通过查看API,发现statusCode参数用来做这件事再好不过了,而且重要的是,即使ajax代码中禁用了全局配置(global:false),
关于statusCode的配置都仍然有效(这点对我们之前项目中来说很重要,因为有很多的ajax都禁用了全局的遮罩效果)。
如果不想在每个controller上都加特性,那么可以将filter注册成全局过滤器。
综上,MVC中我们的代码如下:
namespace MySpace { /// <summary> /// 判断是否登录的过滤器 /// </summary> public class JudgmentLoginAttribute : ActionFilterAttribute { //执行Action之前操作 public override void OnActionExecuting(ActionExecutingContext filterContext) { //判断是否登录或是否用权限,如果有那么就进行相应的操作,否则跳转到登录页或者授权页面 string s_accountId = HttpUtility.UrlDecode(CookiesHelper.GetCookieValue("UserID")); string s_loginTime = HttpUtility.UrlDecode(CookiesHelper.GetCookieValue("LoginTime")) == ""?"2000-01-01 00:00:00": HttpUtility.UrlDecode(CookiesHelper.GetCookieValue("LoginTime")); if((DateTime.Now -DateTime.Parse(s_loginTime)).Minutes >30)//超时30分钟则需要重新登录 { if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new HttpStatusCodeResult(499); filterContext.HttpContext.Response.Write("alert('登陆超时或者非法登录,请重新登录!');top.window.location.href='/Auth/Login';"); } else { HttpContext.Current.Response.Write("<script>alert('登陆超时或者非法登录,请重新登录!');top.window.location.href='/Auth/Login';</script>"); } } else { CookiesHelper.SetCookie("LoginTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } } } }
[MySpace.JudgmentLogin] public class HomeController : Controller
$.ajaxSetup({ statusCode: { 499: function (data) { //console.log(data); eval(data.responseText); } } });