码字,杂谈

利用MVC5 Filter实现登录状态的判断

1、定义LoginCheckAttribute过滤器类

利用Session的键值UserName是否为null判断用户是否登录过,如果登录继续,如果没有,跳转到登录页

public class LoginCheckAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // 执行Action之前调用此方法
        var user = filterContext.HttpContext.Session["UserName"];
        if (user == null)
        {
            // filterContext.HttpContext.Response.Redirect("/Home/Login");
            string url = new UrlHelper(filterContext.RequestContext).Action("Login", "Home");
            filterContext.Result = new RedirectResult(url);
        }
    }

    public void OnAuthenicationChallenge(System.Web.Mvc.Filters.AuthenticationChallengeContext filterContext)
    {
        // 在执行Action之后调用此方法
    }
}

两个方法,一个是在Action被执行之前调用,一个是在Action被执行之后,返回视图之前执行,注意区别。

使用IAuthorizationFilter比直接使用内置的AuthorizeAttribute更加灵活。当我们需要在登录验证中实现扩展的时候,IAuthorizationFilter会更加方便扩展。相对来说,AuthorizeAttribute的核心函数AuthorizeCore只返回一个bool值类型,并不能更加细节的体现权限控制。

2、定义登录Action并添加验证控制

在登录的Controller中添加三个Action用于测试,一个主页,一个GET方法登录页,一个POST方法登录页。

public class HomeController : Controller
{
    [LoginCheck]  // 主页需要登录验证,未登录跳转到登录页
    public ActionResult Index()
    {
        ViewBag.Message = Session["UserName"];  // 成功登录会显示用户名
        return View();
    }

    public ActionResult Login()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Login(string username, string password)
    {
        EmployeeContext EmployeeDB = new EmployeeContext("192.168.1.16", "jeremyjone", "123456");
        bool res = EmployeeDB.LoginCheck(username, password);  // 返回数据库的验证结果

        if (res)
        {
            Session["UserName"] = username;  // 将用户添加到Session中
            return RedirectToAction("Index", "Home");  // 成功直接跳转页面
        }
        ViewBag.ErrorMessage = "输入无效";
        return View();
    }
}

用户登录主页时,会首先进行之前写好的登录验证,如果没有登录,会跳转到登录页。登录页验证成功后,会将用户名添加到Session中,注意Session的KEY值需要保持一致,当然,也可以使用Cookie,不过我并不推荐。登陆之后会成功跳转到主页,主页面会显示出当前登录用户名。

《利用MVC5 Filter实现登录状态的判断》

3、扩展需要

上面代码可以方便控制主页的登录验证,如果整个控制器都需要登录验证,那么直接在类名上面套用过滤器即可。

[LoginCheck]  // 整个控制器的所有Action都需要验证登录情况
public class EmployeeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    // ...省略其他代码
}

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注