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

Razor项目登录页面当前用户信息持久化方案咨询

解决Razor Pages登录后用户信息持久化问题

你当前把currentUser存在LoginPage的后台类里,每次页面跳转都会重新实例化页面模型,所以数据肯定会丢。下面给你两种靠谱的解决方式,优先推荐第一种:

1. 用ASP.NET Core身份认证系统(规范且安全)

这是官方推荐的方案,自带身份验证、会话管理、安全防护,比手动存数据靠谱得多。

步骤:

(1)配置身份认证服务

在Program.cs里添加以下配置:

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login"; // 未登录时跳转的登录页路径
        options.ExpireTimeSpan = TimeSpan.FromHours(2); // 会话过期时间
    });

// 别忘了添加授权服务
builder.Services.AddAuthorization();

// 中间件顺序要注意,放在UseRouting之后,UseEndpoints之前
app.UseAuthentication();
app.UseAuthorization();

(2)修改登录逻辑,生成身份票据

验证密码(记得换成BCrypt)后,创建包含用户信息的身份票据并登录:

public async Task<IActionResult> OnPostLogin()
{
    // 先按用户名查询单个用户,不要遍历所有(性能差)
    var userRows = db.ParametryUzivatele(UserNameLogin).Rows;
    if (userRows.Count == 0)
    {
        // 用户名不存在的处理
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }

    var dr = userRows[0];
    // 替换成BCrypt验证(绝对不能明文比较密码!)
    if (BCrypt.Net.BCrypt.Verify(PasswordLogin, dr[2].ToString()))
    {
        // 创建Claims,只存必要的用户信息,别存密码!
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, dr[0].ToString()),
            new Claim(ClaimTypes.Name, dr[1].ToString()),
            // 按需添加其他非敏感信息,比如dr[3]、dr[4]对应的字段
        };

        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));

        // 登录成功后跳转首页或其他页面
        return RedirectToPage("/Index");
    }
    else
    {
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }
}

(3)在其他页面获取用户信息

任何页面的后台类里,都可以通过HttpContext.User获取当前用户的Claims:

public void OnGet()
{
    if (User.Identity.IsAuthenticated)
    {
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        var userName = User.FindFirstValue(ClaimTypes.Name);
        // 按需获取其他Claims,或者根据ID从数据库查询完整用户信息
    }
}

2. 用Session存储(适合简单场景)

如果不想用完整的身份认证,也可以用Session暂存用户信息,但要注意Session是服务器端存储,且不要存敏感数据。

步骤:

(1)配置Session服务

在Program.cs里添加:

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromHours(2);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

// 中间件放在UseRouting之后
app.UseSession();

(2)登录后存储用户信息到Session

修改你的OnPostLogin方法,验证成功后把用户对象序列化存到Session(注意剔除密码!):

public IActionResult OnPostLogin()
{
    var userRows = db.ParametryUzivatele(UserNameLogin).Rows;
    if (userRows.Count == 0)
    {
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }

    var dr = userRows[0];
    if (BCrypt.Net.BCrypt.Verify(PasswordLogin, dr[2].ToString()))
    {
        // 创建用户对象时不要包含密码!
        var currentUser = new User(
            dr[0].ToString(), 
            dr[1].ToString(), 
            // 这里跳过dr[2](密码),只存必要信息
            dr[3].ToString(), 
            dr[4].ToString(), 
            dr[5].ToString()
        );

        // 序列化用户对象并存入Session
        var userJson = System.Text.Json.JsonSerializer.Serialize(currentUser);
        HttpContext.Session.SetString("CurrentUser", userJson);

        return RedirectToPage("/Index");
    }
    else
    {
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }
}

(3)在其他页面读取Session中的用户信息

在目标页面的后台类里读取:

public User currentUser { get; set; }

public void OnGet()
{
    var userJson = HttpContext.Session.GetString("CurrentUser");
    if (!string.IsNullOrEmpty(userJson))
    {
        currentUser = System.Text.Json.JsonSerializer.Deserialize<User>(userJson);
    }
    else
    {
        // 未登录,跳转登录页
        return RedirectToPage("/Login");
    }
}

重要提醒

  • 绝对不要把用户密码存在Session、Cookie或者任何前端可访问/服务器端持久化的存储里,验证后立即丢弃密码字段。
  • 密码验证必须用BCrypt这类哈希算法,禁止明文比较,你的代码里已经标注要替换,一定要尽快改。
  • 遍历所有用户来匹配的方式性能很差,应该直接按用户名查询单个用户,判断是否存在再验证密码。

内容的提问来源于stack exchange,提问作者Drapys

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:22:55