如何在ASP.NET MVC中通过哈希加密存储过程验证账户?
解决账户验证及登录跳转问题
我来帮你搞定这个登录验证的问题,咱们一步步来:
第一步:修正视图模型(关键!)
你现在直接用Users模型作为登录视图的绑定模型是有问题的——因为Users里的Pass是byte[]类型,但视图里输入的是明文密码字符串,模型绑定的时候会直接失败。所以咱们先创建一个专门用于登录的视图模型:
public class LoginViewModel { [Required(ErrorMessage = "请输入用户名")] public string Username { get; set; } [Required(ErrorMessage = "请输入密码")] [DataType(DataType.Password)] public string Password { get; set; } }
然后更新你的登录视图,把模型换成这个新的LoginViewModel,同时优化密码输入框的绑定(用PasswordFor更规范):
@model Warehouse_APP.Models.LoginViewModel @using (Html.BeginForm("Index", "Home", FormMethod.Post)) { <div class="form-group"> <i class="fa fa-user"></i> @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control", @required = "true", @placeholder = "Username" } }) @Html.ValidationMessageFor(model => model.Username) </div> <div class="form-group"> <i class="fa fa-lock"></i> @Html.PasswordFor(model => model.Password, new { @class = "form-control", @required = "true", @placeholder = "Password" }) @Html.ValidationMessageFor(model => model.Password) </div> <div class="form-group"> <input type="submit" class="btn btn-primary btn-block btn-lg" value="Login"> </div> }
第二步:修改HomeController的Post方法,调用存储过程验证
现在咱们可以在控制器里正常接收用户名和明文密码了,接下来用ADO.NET调用你的ValidateAccount存储过程,获取验证结果并处理跳转:
using System.Configuration; using System.Data; using System.Data.SqlClient; [HttpPost] public ActionResult Index(LoginViewModel loginModel) { // 先检查模型验证是否通过(比如用户名/密码是否为空) if (!ModelState.IsValid) { return View(loginModel); } int validationResult = 0; // 替换成你web.config里的连接字符串名称 string connectionString = ConfigurationManager.ConnectionStrings["YourDbConnection"].ConnectionString; using (SqlConnection conn = new SqlConnection(connectionString)) { using (SqlCommand cmd = new SqlCommand("ValidateAccount", conn)) { cmd.CommandType = CommandType.StoredProcedure; // 添加存储过程的参数 cmd.Parameters.Add("@Username", SqlDbType.VarChar, 50).Value = loginModel.Username; cmd.Parameters.Add("@AccountPwd", SqlDbType.VarChar, 100).Value = loginModel.Password; // 配置存储过程的返回值参数 SqlParameter returnParam = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int); returnParam.Direction = ParameterDirection.ReturnValue; conn.Open(); cmd.ExecuteNonQuery(); // 获取存储过程返回的验证结果 validationResult = (int)returnParam.Value; } } if (validationResult == 1) { // 验证成功,跳转到仪表盘页面(替换成你的目标Action) return RedirectToAction("Dashboard", "Home"); } else { // 验证失败,添加错误提示并返回登录页 ModelState.AddModelError("", "用户名或密码不正确"); return View(loginModel); } }
补充说明
- 记得把代码里的
YourDbConnection替换成你实际在web.config中配置的连接字符串名称; - 你的存储过程逻辑是没问题的:通过用户名获取盐值,拼接明文密码后哈希,再和数据库存储的哈希值对比;
- 如果项目用的是Entity Framework 6+,也可以用EF的方式调用存储过程,代码会更简洁:
using (var db = new YourDbContext()) { validationResult = db.Database.SqlQuery<int>( "EXEC ValidateAccount @Username, @AccountPwd", new SqlParameter("@Username", loginModel.Username), new SqlParameter("@AccountPwd", loginModel.Password) ).FirstOrDefault(); }
内容的提问来源于stack exchange,提问作者César Carcamo
相关产品推荐
相关产品推荐

