After the expiration pop-up page AJAX operating license expires jump a holistic approach to the login page

The purpose of introducing this feature is very simple, to prevent forgetting to log out when leaving the station staff, other staff false operation, when a dispute accountable.

Firstly, reference materials under this article:

  Of 0. The  the Http request processing flow  

How IIS, Framework, Asp.Net processing each work is Http request, how to distinguish between different requests, how the data between the IIS, Framework, Asp.Net three flow? 

Capable of handling various application extension, commonly known as ISAPI applications (Internet Server Application Programe Interface, Internet Server Application Programming Interface)
Asp.Net only Server (IIS) is an integral part of it, it is an ISAPI extension.

HttpRuntime Asp.Net class is a main entrance, which has a method called ProcessRequest, this method as a parameter to a HttpWorkerRequest class. Almost HttpRuntime class contains all the information about a single Http request:
the requested file, the server variables, the QueryString, Http header information and the like.
When the contents of the Web.config file is changed or .aspx files are changed, in order to be able to unload running in the same process application (uninstall also to reload), Http requests are divided on the isolated application domain in.
For IIS, it relies HTTP.SYS called built-in drivers to listen for HTTP requests from the outside. When the operating system starts, IIS first register their virtual path in HTTP.SYS.

When entering the Http request Asp.Net Runtime, its pipeline by the managed module (NOTE: Managed Modules) and the handler (NOTE: Handlers) composition, and to handle the Http request by the pipeline.

 

 

 

  1. HttpModule Introduction

一般来说,我们可以将Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。
而 Http Module 的作用是与应用程序事件 密切相关的。

 Asp.Net 内置的 Http Modules

 

  整个过程如下:

  1. 当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。

  2. 在创建Module实例的时候会调用Module的Init()方法。

  3. 在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。

  4. HttpApplication在其应用程序周期中触发各类事件。

  5. 触发事件的时候调用Module在其Init()方法中注册过的方法。

  2. HttpModule模块作用之三通过Session判断用户是否登陆

  3. 判断Session过期

上述两个参考文档是可以直接参考的代码,非原理性讲解。

  4. 利用HttpModule开发asp.net页面、ashx等访问时session失效的统一处理入口

HttpApplication处理事件的先后顺序,不同事件会处理不同的事情,需要注意使用顺序。

  5. ASP.NET三剑客 HttpApplication HttpModule HttpHandler 解析

详细介绍了上述博客提到的HttpApplication、HttpModule、HttpHandler等对象

  6. ASP.NET Session 简单超实用使用总结

  7. ASP.NET 中的 Session 怎么正确使用

  8. ASP.NET的session操作方法总结

上面介绍的方法都是通过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()
    {
    }
}
HttpModule
<?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>
Web.Config

 

 

上述的参考文档及代码是使用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。

  2. Asp.net MVC Session过期异常的处理

该文章介绍了使用Filter进行session过期的判断。
也解决了前文我提到的一个问题,AJAX请求失败的问题。
但是文章还有个问题待解决,难道要在网页上所有的ajax请求处都要加以处理?

  3. 授权过期后AJAX操作跳转到登录页的一种全局处理方式

当授权过期后,针对ajax请求返回一个特定的标识,然后前端通过识别该标识,来跳转到登录页面。而且最好不用在每处ajax请求的代码中都加上对这种标识判断,即要能全局处理。
所以目标就落在了jQuery.ajax的全局配置($.ajaxSetup)上了,通过查看API,发现statusCode参数用来做这件事再好不过了,而且重要的是,即使ajax代码中禁用了全局配置(global:false),
关于statusCode的配置都仍然有效(这点对我们之前项目中来说很重要,因为有很多的ajax都禁用了全局的遮罩效果)。

  4. MVC过滤器处理Session过期

如果不想在每个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"));
            }
        }
    }
}
JudgmentLoginAttribute
[MySpace.JudgmentLogin]
public class HomeController : Controller
特性
$.ajaxSetup({
            statusCode: {
                499: function (data) {
                    //console.log(data);
                    eval(data.responseText);
                }

            }
        });
页面加上JS

 

Guess you like

Origin www.cnblogs.com/lq67/p/11307359.html