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

基于SQLite的Razor页面登录:当前用户会话存储方案咨询

Razor页面登录会话用户信息存储方案

一、先修正你的User模型问题

你的User类构造函数存在逻辑错误:在Users.Add(new User(ID,UserName,Password,Email,LevelOfAccess,Verified));这一行,ID、UserName等字段还未被赋值,会导致添加的是默认值的空User对象;同时单个User实例不需要维护List<User>集合,完全是冗余设计。修正后的模型如下:

public class User
{
    public int ID { get; set; }
    public string? UserName { get; set; }
    public string? Password { get; set; }
    public string? Email { get; set; }
    public int LevelOfAccess { get; set; }
    public int Verified { get; set; }

    // 业务构造函数
    public User(int id, string userName, string password, string email, int levelOfAccess, int verified)
    {
        ID = id;
        UserName = userName;
        Password = password;
        Email = email;
        LevelOfAccess = levelOfAccess;
        Verified = verified;
    }

    // EF Core要求的无参构造函数(从数据库加载实体时需要)
    public User() {}
}

二、跨页面共享登录用户的正确方案:ASP.NET Core Session

Razor Pages中,Session是专门为用户会话隔离存储数据的机制,完美适配你的需求——每个登录用户的信息独立存储,所有页面都能访问。

步骤1:启用Session服务

在Program.cs中配置并启用Session:

var builder = WebApplication.CreateBuilder(args);

// 添加Session服务,配置超时和安全属性
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30); // 会话闲置30分钟后过期
    options.Cookie.HttpOnly = true; // 禁止前端JS访问Cookie,防止XSS窃取
    options.Cookie.IsEssential = true; // 标记为必要Cookie,符合隐私合规要求
});

builder.Services.AddRazorPages();

var app = builder.Build();

// 启用Session中间件(必须放在UseRouting之后、UseAuthorization之前)
app.UseSession();

app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();

app.Run();

步骤2:登录时将用户信息存入Session

修改你的OnPostLogin方法,必须先验证密码(你的原代码完全缺失这一步,是严重的安全漏洞),再将用户对象序列化后存入Session:

using System.Text.Json;

public async Task<IActionResult> OnPostLogin()
{
    // 1. 从数据库查询用户数据
    var userData = db.ParametryUzivatele(UserNameLogin);
    if (userData.Rows.Count == 0)
    {
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }

    // 2. 验证密码(数据库必须存哈希后的密码,绝对不能存明文!)
    var storedPasswordHash = userData.Rows[2].ToString();
    if (!VerifyPassword(PasswordLogin, storedPasswordHash))
    {
        ModelState.AddModelError("", "用户名或密码错误");
        return Page();
    }

    // 3. 构造User对象
    var currentUser = new User(
        Convert.ToInt32(userData.Rows[0]),
        userData.Rows[1].ToString(),
        storedPasswordHash,
        userData.Rows[3].ToString(),
        Convert.ToInt32(userData.Rows[4]),
        Convert.ToInt32(userData.Rows[5])
    );

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

    // 5. 登录成功跳转至主页
    return RedirectToPage("/Index");
}

// 密码验证方法(示例:使用ASP.NET Core官方的PasswordHasher)
private bool VerifyPassword(string inputPassword, string storedHash)
{
    var hasher = new PasswordHasher<User>();
    return hasher.VerifyHashedPassword(null, storedHash, inputPassword) == PasswordVerificationResult.Success;
}

步骤3:创建基类统一获取当前用户

为了避免每个页面重复编写Session读取逻辑,创建一个基类BasePageModel,让所有需要访问用户信息的页面继承它:

using System.Text.Json;
using Microsoft.AspNetCore.Mvc.RazorPages;

public class BasePageModel : PageModel
{
    protected User? CurrentUser { get; set; }

    public override void OnPageHandlerExecuting(Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext context)
    {
        var userJson = HttpContext.Session.GetString("CurrentUser");
        if (!string.IsNullOrEmpty(userJson))
        {
            CurrentUser = JsonSerializer.Deserialize<User>(userJson);
        }
        base.OnPageHandlerExecuting(context);
    }
}

之后你的页面Model只需继承基类,就能直接使用CurrentUser:

public class IndexModel : BasePageModel
{
    public void OnGet()
    {
        if (CurrentUser != null)
        {
            // 示例:将用户名传递给视图
            ViewData["CurrentUserName"] = CurrentUser.UserName;
        }
    }
}

三、关键注意事项

  • 密码安全:永远不要在数据库中存储明文密码,必须使用BCrypt、PBKDF2等强哈希算法存储密码哈希值。
  • Session数据精简:只存储必要的用户信息(如ID、用户名、权限等级),大量数据请在需要时从数据库查询,避免Session体积过大。
  • 登录校验:在需要权限的页面,要检查CurrentUser是否为null,若为空则强制跳转到登录页面,可在基类中统一实现。
  • 序列化兼容性:确保User类无循环引用(原模型的List<User>会导致序列化失败),所有属性可被JSON序列化。

内容的提问来源于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 17:58:24