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

ASP.NET Core:如何从用户数据库获取指定UserPass实现登录验证

登录系统密码校验问题简化解决方案

问题背景

我正在开发登录系统,需要从用户数据库获取UserPass字段,与用户输入的密码比对完成登录验证。目前已经实现用户名存在性校验,程序是ASP.NET 6.0 Core Web App,能正常访问数据库,创建功能测试可用。我只掌握ASP.NET Core基础,想要简化的解决方案说明。

现有代码

LoginPage.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using AQA_A_Level_CS_NEA__Suvat_Solver_.Models;
using AQA_A_Level_CS_NEA__Suvat_Solver_.Data;

namespace AQA_A_Level_CS_NEA__Suvat_Solver_.Pages.UserLogin
{
    [BindProperties(SupportsGet = true)]
    public class LoginPageModel : PageModel
    {
        public new TempUserLoginModel TempUser { get; set; }
        public bool HasPassword { get; set; } = true;
        public bool HasUsername { get; set; } = true;
        public bool IncorUsername { get; set; } = false;
        public bool LoginApproved { get; set; }
        public bool RegisterApproved { get; set; }

        private readonly ApplicationDbContext _context;
        public LoginPageModel(ApplicationDbContext context)
        {
            _context = context;
        }
        public List<User> UserList = new List<User>();

        public void OnGet()
        {

        }
        public IActionResult OnPost()
        {
            User User = new User();
            HasPassword = true;
            HasUsername = true;
            IncorUsername = false;
            UserList = _context.User.ToList();

            if (string.IsNullOrWhiteSpace(TempUser.Password))
            {
                HasPassword = false;
            }
            if (string.IsNullOrWhiteSpace(TempUser.Username))
            {
                HasUsername = false;
            }
            if (UserList.Any(x => x.UserName == TempUser.Username))
            {
                string passtocheck = User.UserPass
                    .Where(x => x.UserName == TempUser.Username);
                //my attempted method that does not work

                if (passtocheck == TempUser.Password)
                {
                    //this is where i would like to determine that password is correct
                    LoginApproved = true;
                }
            }
            else
            {
                IncorUsername = true;
            }
            if (!HasPassword || !HasUsername || IncorUsername)
            {
                return RedirectToPage("/UserLogin/LoginPage", new {HasPassword,HasUsername,IncorUsername});
            }
            else
            {
                return RedirectToPage("/Index", new { LoginApproved });
            };
        }
    }
}

User.cs模型

namespace AQA_A_Level_CS_NEA__Suvat_Solver_.Models
{
    public class User
    {
        public int UserId { get; set; }
        public string UserName { get; set; } = string.Empty;
        public string UserPass { get; set; } = string.Empty;
        public int UserCorrectAnsw { get; set; } = 0;
        public int UserTotalAnsw { get; set; } = 0;

        public List<UsertoCourses> UsertoCourses { get; set; }
    }
}

核心错误分析

你当前的密码校验逻辑完全错误:

  • 新建了空的User对象,然后试图从它的UserPass(单个字符串)调用Where方法——Where是集合的方法,字符串根本没有这个方法。
  • 没必要把所有用户都加载到UserList里,既浪费内存又低效,直接查询匹配用户名的用户即可。

简化修正方案

1. 替换核心校验逻辑

直接从数据库查询匹配用户名的用户,然后比对密码:

// 替代原有的UserList查询和密码校验代码
var existingUser = _context.User.FirstOrDefault(x => x.UserName == TempUser.Username);
if (existingUser != null)
{
    if (existingUser.UserPass == TempUser.Password)
    {
        LoginApproved = true;
    }
    else
    {
        // 新增密码错误标记,用于页面提示
        bool WrongPassword = true;
    }
}
else
{
    IncorUsername = true;
}

2. 完整修正后的OnPost方法

public IActionResult OnPost()
{
    HasPassword = true;
    HasUsername = true;
    IncorUsername = false;
    LoginApproved = false;
    // 新增密码错误标记,方便页面提示用户
    bool WrongPassword = false;

    // 先校验输入是否为空
    if (string.IsNullOrWhiteSpace(TempUser.Password))
    {
        HasPassword = false;
    }
    if (string.IsNullOrWhiteSpace(TempUser.Username))
    {
        HasUsername = false;
    }

    // 只有输入合法时才查询数据库
    if (HasPassword && HasUsername)
    {
        // 直接查询匹配用户名的用户,不用加载全表
        var existingUser = _context.User.FirstOrDefault(x => x.UserName == TempUser.Username);
        if (existingUser != null)
        {
            // 比对密码
            if (existingUser.UserPass == TempUser.Password)
            {
                LoginApproved = true;
            }
            else
            {
                WrongPassword = true;
            }
        }
        else
        {
            IncorUsername = true;
        }
    }

    // 有任何错误就返回登录页,携带错误状态
    if (!HasPassword || !HasUsername || IncorUsername || WrongPassword)
    {
        return RedirectToPage("/UserLogin/LoginPage", new { HasPassword, HasUsername, IncorUsername, WrongPassword });
    }
    else
    {
        return RedirectToPage("/Index", new { LoginApproved });
    }
}

3. 额外优化点

  • 删掉没用的User User = new User();和public List<User> UserList = new List<User>();,这些都是冗余代码。
  • 如果需要在登录页显示密码错误提示,要在PageModel里新增public bool WrongPassword { get; set; } = false;属性,然后在Razor页面里添加对应的提示逻辑。

基础学习者提示

  • 密码安全:实际项目绝对不能明文存储密码,应该用ASP.NET Core自带的PasswordHasher或者BCrypt加密存储,比对时用哈希校验。如果是学校NEA项目,老师没要求的话可以先按明文处理,之后再优化。
  • 查询效率:用FirstOrDefault直接查询匹配的用户,比加载全表再判断高效得多,用户量越大差异越明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:36:23