我制作了一个密码重置控制器,它接受GUID查询字符串。正如您在下面的代码中看到的,我的控制器检查我的数据库中是否存在GUID值,然后它将user
返回到具有属性name和userId的视图。
[HttpGet]
public ActionResult RetreivePass(string ac)
{
MySqlContext db = new MySqlContext();
PwRetreival PwRetreival = new PwRetreival();
Users user = new Users();
if (db.PwRetreival.FirstOrDefault(u => u.Token == ac) != null)
{
PwRetreival.uId = db.PwRetreival.Where(u => u.Token == ac).Select(u => u.uId).First();
var Attributes = db.Users.Where(u => u.UserId == PwRetreival.uId).Select(u => new { u.Name, u.UserId }).FirstOrDefault();
user.Name = Attributes.Name;
user.UserId = Attributes.UserId;
return View(user);
}
return RedirectToAction("Index", "Home");
}
在我看来,它看起来像这样:
<p>Hello @Model.Name</p>
@using (Html.BeginForm(FormMethod.Post))
{
<p>Change password</p>
@Html.TextBoxFor(u => u.Password)
<p>
<button type="submit">Register</button>
</p>
}
最后,提交后,我打电话给这个控制器:
[HttpPost]
public string RetreivePass(Users model)
{
//Some code here
}
不幸的是,我的问题是,在提交时,参数(Name&amp; UserId)不会随模型一起返回给控制器。因此我只有密码,我无法用于任何事情,因为我无法告诉我的控制器在哪里放置更新的密码。
我错过了什么吗?
为方便起见,我的模型如下:
public class Users
{
[Key]
public int UserId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Name { get; set; }
public short EmailConfirmed { get; set; }
}
public class PwRetreival
{
[Key]
public int Id { get; set; }
public int uId { get; set; } //FK to Users.UserId
public string Token { get; set; }
}
答案 0 :(得分:0)
确保将名称包含在表单中作为一些输入参数(如果用户不应该修改它,则隐藏):
@using (Html.BeginForm(FormMethod.Post))
{
<p>Change password</p>
@Html.HiddenFor(u => u.UserId)
@Html.TextBoxFor(u => u.Password)
<p>
<button type="submit">Register</button>
</p>
}
因此,基本上您希望在回发时检索的所有参数都必须包含在表单内的输入字段或查询字符串参数中。
当然,您意识到隐藏字段或查询字符串参数可以从外部修改,使其非常不安全。知道另一个用户的UserId
的任何人都可以为他触发密码重置。为了实现安全的密码重置功能,您可能需要一些加密。例如,您可以使用对称加密算法来加密UserId
,并在密码重置电子邮件中将加密值发送到客户端。然后,当表单被POST回来时,可以在服务器上解密加密值以提取原始客户端ID和新密码。如果加密值已被篡改,您将立即知道。
另一种方法是在服务器上生成一些令牌,该令牌将与您的用户关联并存储在您的后端。然后通过密码重置电子邮件将此令牌发送给客户端,当回发后,您将通过查看后端知道原始用户是谁。使用服务器密钥签署此令牌也是一个好主意,以确保它没有被篡改。