[转]MVC 检测用户是否已经登录
本文转自:http://blog.csdn.net/jayzai/article/details/41252137
当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的OnInit()方法,在OnInit()中判断Session中是否有用户登录的信息
- ///<summary>
- /// 公共基类里面干一些公共的事情
- ///</summary>
- public class BasePage : System.Web.UI.Page
- {
- //页面生命周期Init事件对应的OnInit()方法
- //这个方法会先于PageLoad方法执行
- //override 表示重写 OnInit方法OnInit 方法,在所有控件都已初始化且已应用所有外观设置后引发。使用该事件来读取或初始化控件属性
- protected override voidOnInit(EventArgs e)
- {
- base.OnInit(e);
- if (Session["UserInfo"] == null) //检查用户是否登录
- {
- //跳转到登录页面
- }
- }
- }
///<summary>
/// 公共基类里面干一些公共的事情
///</summary>
public class BasePage : System.Web.UI.Page
{
//页面生命周期Init事件对应的OnInit()方法
//这个方法会先于PageLoad方法执行
//override 表示重写 OnInit方法OnInit 方法,在所有控件都已初始化且已应用所有外观设置后引发。使用该事件来读取或初始化控件属性
protected override voidOnInit(EventArgs e)
{
base.OnInit(e);
if (Session["UserInfo"] == null) //检查用户是否登录
{
//跳转到登录页面 }
}
}
在mvc下该怎样校验呢? 我们知道,MVC下可以自定义特性类为控制器或控制器中的Action打上[特性],这里只需要ActionFilter过滤器(Action方法执行前后执行),MVC提供了IActionFilter接口。(为了方便我们可以用微软提供好的ActionFilterAttribute类,他是筛选器特性的基类,也是一个抽象类,其实这个抽象类实现了IActionFilter和IResultFilter) IActionFilter接口的定义:
//在执行操作方法后调用。
void OnActionExecuted(ActionExecutedContext filterContext);
// 在执行操作方法之前调用。
void OnActionExecuting(ActionExecutingContext filterContext);
新建一个特性类LoginCheckFilterAttribute,让他继承ActionFilterAttribute,并重写其中的OnActionExecuting方法,在其中完成校验
public class LoginCheckFilterAttribute :ActionFilterAttribute { }
//表示是否检查登录 public bool IsCheck { get; set; }
- //Action方法执行之前执行此方法
- public overridevoid OnActionExecuting(ActionExecutingContext filterContext)
- {
- base.OnActionExecuting(filterContext);
- if (IsCheck)
- {
- //校验用户是否已经登录
- if (filterContext.HttpContext.Session["loginUser"] ==null)
- {
- //跳转到登陆页
- filterContext.HttpContext.Response.Redirect("/UserLogin/Index");
- }
- }
- else{
- //跳转到首页
- filterContext.HttpContext.Response.Redirect("/Home/Index");
- }
- }<span style="font-size:14px;">怎么让这个过滤器起作用呢?</span>
//Action方法执行之前执行此方法
public overridevoid OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (IsCheck)
{
//校验用户是否已经登录
if (filterContext.HttpContext.Session["loginUser"] ==null)
{ //跳转到登陆页
filterContext.HttpContext.Response.Redirect("/UserLogin/Index"); }
}
else{ //跳转到首页
filterContext.HttpContext.Response.Redirect("/Home/Index");
}
}<span style="font-size:14px;">怎么让这个过滤器起作用呢?</span>
步骤:
1、在Global.asax文件中为MVC程序注册全局过滤器, 调用FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)。
FilterConfig类在App_Start文件夹中(创建新的MVC项目会自动生成)。
- 在FilterConfig的静态方法中
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)注册全局过滤器
- public class FilterConfig
- {
- //这个方法是用于注册全局过滤器(在Global中被调用)
- public static voidRegisterGlobalFilters(GlobalFilterCollection filters)
- {
- //filters.Add(newHandleErrorAttribute());
- filters.Add(newLoginCheckFilterAttribute() { IsCheck = true });
- }
- }
在FilterConfig的静态方法中
public static void RegisterGlobalFilters(GlobalFilterCollection filters)注册全局过滤器
public class FilterConfig
{
//这个方法是用于注册全局过滤器(在Global中被调用)
public static voidRegisterGlobalFilters(GlobalFilterCollection filters)
{ //filters.Add(newHandleErrorAttribute());
filters.Add(newLoginCheckFilterAttribute() { IsCheck = true }); }
}
注意要为特性类实例的IsCheck属性赋值true否则Session校验不起作用。
这样子,LoginCheckFilterAttribute这个特性就会对整个MVC程序中的控制器和Action起作用了,就是说在执行Action方法之前会先调用特性类中的重写OnActionExecuting方法,这样用户在访问网站的时候会首先检测用户是否已经登录,如果没有登录会跳转到登录页面。
但是!但是!问题来了,因为我们注册的是全局的过滤器,这个过滤特性会对所有的控制器下的Action起作用,当访问网站的时候会(比如我们注册默认路由为/Home/Index)会首先跳转到/Home/Index,这时不会执行Index方法,会先执行OnActionExecuting()中的校验,发现Session为null,Response.Redirect("/UserLogin/Index")跳转到了登录页面;这时我们在浏览器中依然看不到登录页面,为什么呢?还记得我们注册的全局的过滤器,作用对象包括所有控制器下的Action当然也包括/UserLogin/Index,代码走到了这里会再次执行OnActionExecuting()方法,发现Session["UserInfo"==]null,又跳到了登录页面,我们连登录页面都见不着肯定不能输入用户名密码Session也就不会有登录信息,浏览器会返回 ”此网页包含重定向循环“ 的错误页面,也就是说会一直循环不停的重定向到登录页面,类似死循环,浏览器当然罢工了。
该怎样解决这个bug的?
我尝试了两种解决办法:
方法1:为UserLoginController控制器打上特性
[LoginCheckFilterAttribute(IsCheck= false)] //打上用户登录校验特性(IsCheck设为false不让它对此控制器起作用,而对其他控制器和Action起作用,防止重定向循环) public class UserLoginController :Controller { ... }
我们在定义这个特性类的时候 有个bool属性 IsCheck,它表示是否校验,这里设为false表示不校验。顺便说一下LoginCheckFilterAttribute可以省略Attrbute后缀。
一定要在控制器上打这个特性,不要只针对下边的某个Action,因为这里边有生成验证码的Action和处理登录请求的Action,它们都不需要进行session校验(没意义),在控制器上打上特性会对它下边的所有Action起作用,不用为每个Action打特性了,节省代码量。我们注册了全局过滤器,又单独为UserLoginController控制器打上过滤特性,这里有一个优先级的问题Action>Controller>全局,UserLoginController不会受全局过滤器的影响。
到这里测试一下,输入网站地址,成功进入登录页面,输入正确的用户名密码点击登录,浏览器又返回了
的错误信息,调试了一下还是之前那个问题,只不过能显示了登录页面,登录后Session["UserInfo"]有了用户,依然会无限重定向,因为会在OnActionExecuting()在Action之前执行,这时即使Sessio["UserInfo"]!=null,也会造成死循环,解决方案:
- 执行时出报异常,这时要在Global.asax里添加:开启Session功能
- public class WebApiApplication : System.Web.HttpApplication
- {
- public override void Init()
- {
- this.PostAuthenticateRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
- base.Init();
- }
- }
执行时出报异常,这时要在Global.asax里添加:开启Session功能
public class WebApiApplication : System.Web.HttpApplication
{
public override void Init()
{
this.PostAuthenticateRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
base.Init();
}
}
方法2:利用BaseController类(类似WebFrom的BasePage)
1、新建一个BaseController类,继承System.Web.Mvc.Controller,类中定义一个UserInfo属性,保存从Session["UserInfo"]中拿出的用户实体,方便他的派生类调用。
2、F12定义一下System.Web.Mvc.Controller这个类发现
public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter,IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController,IAsyncManagerContainer { //...}
它竟然也实现了IActionFilter接口,那就用不着上面我们的全局过滤器了,只需要重写OnActionExecuting()方法,逻辑和过滤器中的代码一样,让需要进行登录校验的控制器来继承BaseController类就可以了,相当于为BaseController控制器打上了上面的校验特性, 完美解决登录校验的问题。
[转]MVC 检测用户是否已经登录的更多相关文章
- MVC 检测用户是否登录
当我们访问一个网站的需求检測用户是否已经登录(通过Session是否为null),我们知道在WebForm中能够定义一个BasePage类让他继承System.Web.UI.Page,重写它 ...
- MVC下用户登录状态校验的问题以及解决方案--------------Action全局过滤器的使用
前言当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的 ...
- [转载]MVC中单用户登录
转自:http://www.cnblogs.com/firstcsharp/archive/2013/05/19/3087481.html 把下面这段代码放在登录用户验证以后: //用户登录验证通 ...
- day108:MoFang:首页检测用户是否登录&在项目中使用MongoDB&用户页面更新用户信息&交易密码界面实现
目录 1.首页页面也要检测用户是否登录 2.在flask中使用MongoDB 3.用户页面更新用户信息 4.交易密码界面/密码修改界面/昵称修改界面初始化 5.交易密码实现 1.首页页面也要检测用户是 ...
- 七天学会ASP.NET MVC (四)——用户授权认证问题
小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...
- 七天学会ASP.NET MVC (四)——用户授权认证问题 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1)
系列目录 前言: WebAPI主要开放数据给手机APP,其他需要得知数据的系统,或者软件应用,所以移动端与系统的数据源往往是相通的. Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能, ...
- 过滤器(Filter)案例:检测用户是否登陆的过滤器
*****检测用户是否登陆的过滤器:不需要用户跳转到每个页面都需要登陆,访问一群页面时,只在某个页面上登陆一次,就可以访问其他页面: 1.自定义抽象的 HttpFilter类, 实现自 Filter ...
- MVC WebApi 用户验证 (2)
构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2) 前言: 构建ASP.NET MVC5+EF6+E ...
随机推荐
- 用Java编写的http下载工具类,包含下载进度回调
HttpDownloader.java package com.buyishi; import java.io.FileOutputStream; import java.io.IOException ...
- node-orm2
最近应老大要求,对orm2进行再一步封装,所以记录下封装和使用心得(文中数据库:mysql). 数据库连接 var orm = require("orm"); orm.connec ...
- Linux epoll 源码注释
https://www.cnblogs.com/stonehat/p/8613505.html 这篇文章值得好好读,先留个记录,回头看. IO多路复用之epoll总结 - Anker's Blog - ...
- oracle case where 复杂sql语句
update hr_user u set u.is_approve=(case when u.curr_org_id in (select t.org_id from hr_organization ...
- 微信小程序 新手入门教程
因为工作需要,最近学习了一下微信小程序,在此分享一下大概的流程. 强烈建议大家先去看微信小程序简易教程:点我进入 起步: 安装微信web开发软件者工具,需要破解的同学可以网上找破解教程,很简单的,这里 ...
- python大法好 vijos1375 大整数
一个k(1<=k<=80)位的十进制正整数N,就是所谓的大整数.请你设计程序,对于给出的某一个大整数N,找到满足p^3+p^2+3p<=n的p的最大值. 输入格式 输入数据只有一行, ...
- HDU1532 Drainage Ditches —— 最大流(sap算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532 Drainage Ditches Time Limit: 2000/1000 MS (Java/ ...
- maven配置本地仓库和国内镜像仓库,解决国内访问国外中央仓库速度过慢问题
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 1.配置本地仓库 打开conf文件夹下面的setting.xml文件 红色方框为配置本地仓 ...
- html5--6-41 CSS背景
html5--6-41 CSS背景 实例 学习要点 掌握CSS背景属性的使用 元素的背景属性: background 简写属性,作用是将背景属性设置在一个声明中. background-attachm ...
- Swagger测试工具
http://www.360doc.com/content/16/0509/08/1355383_557462195.shtml