You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中注册全局过滤器即可
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            // 注册自定义登录校验为全局过滤器
            filters.Add(new LoginCheckAttribute());
            filters.Add(new HandleErrorAttribute());
        }
    }
    
    注意:全局注册后,登录、注册这类不需要登录就能访问的页面/接口,要给对应的Action或者Controller加[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:15:37