ASP.NET Core MVC如何实现仅登录用户可访问页面
ASP.NET MVC 基于Session实现登录状态拦截
ASP.NET MVC 没有Web Forms的页面生命周期模型,不需要在每个页面的Page_Load里重复写校验逻辑,官方提供的授权过滤器机制可以实现更灵活的请求拦截,完全可以对齐你原来Web Forms的登录校验效果,维护成本更低。
1. 登录成功时的Session写入
这部分和你Web Forms的写法几乎没有区别,在登录提交的Action中,校验用户身份凭证通过后直接写入Session即可:
[HttpPost] [AllowAnonymous] // 后续配置全局校验时,必须给登录相关接口加这个特性,否则会触发无限重定向 public ActionResult Login(LoginViewModel model) { if (ModelState.IsValid) { // 替换成自己的用户名、密码校验逻辑 var user = _userService.ValidateUser(model.UserName, model.Password); if (user != null) { // 和Web Forms的Session写入逻辑完全一致 Session["UserID"] = user.Id; // 登录成功后跳转 return RedirectToAction("Index", "Home"); } ModelState.AddModelError("", "用户名或密码错误"); } return View(model); }
2. 实现自定义授权拦截器
拦截器会在目标请求执行前触发,完全替代你原来写在Page_Load里的登录判断、未登录跳转逻辑:
using System.Web.Mvc; /// <summary> /// 自定义登录校验特性 /// </summary> public class LoginCheckAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { // 核心判断逻辑:检测Session中是否存在UserID return httpContext.Session["UserID"] != null; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { // 校验不通过时跳转到登录页 filterContext.Result = new RedirectResult("~/Account/Login"); } }
3. 按需配置拦截范围
你可以根据业务需求把校验特性挂在不同层级,不用每个页面重复写判断:
- 全局生效:对站点所有Action都做登录校验,在
App_Start/FilterConfig.cs中注册全局过滤器即可
注意:全局注册后,登录、注册这类不需要登录就能访问的页面/接口,要给对应的Action或者Controller加public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // 注册自定义登录校验为全局过滤器 filters.Add(new LoginCheckAttribute()); filters.Add(new HandleErrorAttribute()); } }[AllowAnonymous]特性跳过校验。 - 控制器级生效:只对某个控制器下的所有Action加校验,直接把特性标在控制器类上即可
[LoginCheck] public class UserCenterController : Controller { // 这个控制器下所有Action都会自动做登录校验 public ActionResult Index() { return View(); } } - 单页面/单接口生效:只需要给单个Action加校验的话,直接把特性标在对应Action方法上即可
public class HomeController : Controller { public ActionResult Index() { return View(); } [LoginCheck] public ActionResult PersonalInfo() { // 只有访问这个页面时才会校验登录状态 return View(); } }
轻量场景替代方案
如果只是单个Controller下需要做校验,不想单独写过滤器类,也可以直接在Controller里重写OnActionExecuting方法,逻辑和你原来写在Page_Load里的代码几乎一致:
public class UserCenterController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { // 和原Page_Load里的判断逻辑完全对应 if (Session["UserID"] == null) { filterContext.Result = new RedirectResult("~/Account/Login"); return; } base.OnActionExecuting(filterContext); } public ActionResult Index() { return View(); } }
这个方案缺点是复用性差,多个Controller需要校验时要重复写代码,只适合小范围临时使用,长期维护还是推荐自定义授权过滤器的方案。
内容的提问来源于stack exchange,提问作者xandune
相关产品推荐
相关产品推荐

