【发布时间】:2018-03-06 17:25:13
【问题描述】:
我有这个简单的用户类,对于 Password 属性,我想将 getter 设为私有(仅在内部使用 - 公开一个公共的 VerifyPassword 方法,该方法将在内部执行验证并返回一个布尔值)
现在问题来自我的控制器中路由上的模型绑定。当我尝试使用 asp-for 标签助手指向 Model.Password 时,它告诉我“密码不能在这种情况下使用,因为 get-accessor 不可用”
我是初学者。我认为将 getter 设为私有是保护它不被暴露的明智之举。但是现在我不能在模型绑定中使用它。
所以有几个问题: 这是保护密码的正确方法吗? 这是使用模型绑定的正确方法吗? 有什么可以改进的建议吗?
这是模型:
using System;
namespace user_signup.Models {
public class User
{
private string username;
private string email;
private string password;
public string Username {
get => username;
set {
if (value.Length < 5) {
throw new ArgumentException("Username is too short.");
}
if (value.Length > 15) {
throw new ArgumentException("Username is too long.");
}
username = value;
}
}
public string Email {
get => email;
set {
// email validation here
email = value;
}
}
public string Password {
// the getter is private (only accessable internally)
private get => password;
set {
if (value.Length < 5) {
throw new ArgumentException("Password is too short.");
}
if (value.Length > 15) {
throw new ArgumentException("Password is too long.");
}
password = value;
}
}
// public means of verifying a password (the password itself is never exposed)
public bool VerifyPassword(string pass) => Password.Equals(pass);
// counter of all users that have been instantiated (prevents overlapping IDs)
// static so it is at the Class level (can be counted globally outside of all User instances)
private static int NextId = 0;
// can only be set internally (private setter)
// defaults to the CURRENT VALUE of NextId and THEN increments NextId for the next instantiation
public int UserId { get; } = NextId++;
// can only be set internally (private setter)
// defaults to current DateTime in string format
public string CreateDate { get; private set; } = DateTime.Now.ToString();
// the model will be populated from form data sent in a Request
public User() {}
// for creating a user by other means (manually)
public User(string u, string e, string p) {
Username = u;
Email = e;
Password = p;
}
public override string ToString() {
return String.Format(
"UserId: {0}\nUsername: {1}\nEmail: {2}\n\n",
UserId,
Username,
Email
);
}
}
}
这里是控制器(特别是 Add.cshtml GET 和 POST 处理程序)
[HttpGet]
public IActionResult Add() {
VModel.User = new User();
return View(VModel);
}
[HttpPost]
public IActionResult Add(User user, string verify) {
VModel.User = user;
VModel.Users = Users.GetUsers();
if (!user.VerifyPassword(verify)) {
VModel.Errors["verify"] = "Verify password failed. Passwords do not match.";
return View(VModel);
}
return View("Index", VModel);
}
最后是 Add.cshtml 视图
@using user_signup.Controllers
@model UserController.ViewModel
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
<div>
<form asp-controller="User" asp-action="Add" method="post">
<label>Username: </label>
<input type="text" asp-for="@Model.User.Username" required/>
<label>Email: </label>
<input type="text" asp-for="@Model.User.Email"/>
<label>Password: </label>
<input type="password" asp-for="@Model.User.Password" required/>
<label>Verify Password: </label>
<input type="password" name="verify" required/>
<input type="submit" value="Sign Up"/>
</form>
</div>
</body>
</html>
【问题讨论】:
-
公开即可。由于上述原因,没有必要将其设为私有。阅读以下内容,了解为什么要将属性设为私有:stackoverflow.com/questions/3847832/…
-
@RichardMc 这是在谈论私人二传手。我有一个私人 getter,所以密码只能在课堂内部读取
-
我不是要争论。我只是想知道为什么这不是一个好主意,所以我可以学习。我的直觉是,将 getter 设为私有对于密码属性会更安全。你能纠正我的直觉,这样我就可以学习了
-
我想你可能对私有的目的有点困惑。您说得对,它限制了对其当前类的访问,但除非您不信任自己的代码,否则它不会使密码属性更安全。密码安全与您存储和传输密码的方式有关。 tchelidze 下面概述的内容描述了如何正确保护密码。那里有很多,但值得了解。
标签: c# razor asp.net-core-mvc private model-binding