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
相关产品推荐
相关产品推荐

