简体   繁体   English

如何检查输入的密码是否等于存储的密码?

[英]How to check if entered password is equal to stored password?

Suppose I've implemented a method to change the password in the user panel. 假设我已经实现了一种在用户面板中更改密码的方法。 Before doing the change, I ask to the user to enter the current password, I actually created this method: 在进行更改之前,我要求用户输入当前密码,而我实际上创建了此方法:

[HttpPost]
[ValidateAntiForgeryToken]
public bool CheckCurrentPassword(string username, string password)
{
    var originalUser = _userManager.Users.FirstOrDefault(c => c.UserName == username);
    var hash = _userManager.PasswordHasher.HashPassword(originalUser, password);

    if (hash == originalUser.PasswordHash)
        return true;

    return false;
}

essentially I send to this method the username which is an unique field and I can retrieve the user which asked for password change. 本质上,我向该方法发送的username是唯一字段,并且我可以检索要求更改密码的用户。 I get also the hash of the new password and then compare the hash to the stored hash in the database. 我还获得了新密码的哈希值,然后将该哈希值与数据库中存储的哈希值进行比较。

The problem is that the hash is different. 问题在于哈希是不同的。 I don't know why but with the same password I have two different hashes (one stored in the db) and another generated on the fly by the method. 我不知道为什么,但是使用相同的密码,我有两个不同的哈希值(一个存储在数据库中),另一个由该方法动态生成。

Maybe there is another way to check if the current password is equal to the entered password? 也许还有另一种方法来检查当前密码是否等于输入的密码?

This is exactly what UserManager<TUser>.CheckPasswordAsync(TUser, String) is for: 这正是UserManager<TUser>.CheckPasswordAsync(TUser, String)的用途:

if (await _userManager.CheckPasswordAsync(originalUser, password))
{
    // Yes, it's the current password.
}

While you're at it, you're better off using UserManager.FindByNameAsync(String) to get your originalUser . 进行此操作时,最好使用UserManager.FindByNameAsync(String)来获取originalUser The entire function could become: 整个功能可能变为:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<bool> CheckCurrentPassword(string username, string password)
{
    var originalUser = await _userManager.FindByNameAsync(username);

    // originalUser might be null (as in your example), so check for that accordingly.

    return await _userManager.CheckPasswordAsync(originalUser, password);
}

Using the Async methods requires your calling code to use async/await , which I've folded into the example above. 使用Async方法需要您的调用代码使用async/await ,我已将其折叠到上面的示例中。 Actions support this out of the box; 动作支持开箱即用; handling a return type of Task<T> . 处理Task<T>的返回类型。

If you're interested in how the CheckPasswordAsync function is implemented, you can see for yourself in the source code , which might help you determine why your own version isn't working. 如果您对CheckPasswordAsync函数的实现方式感兴趣,可以在源代码中自己查看,这可以帮助您确定自己的版本为何不起作用。

If the hashes are different then the method used to hash the password before entering it into the database must be different from _userManager.PasswordHasher.HashPassword . 如果哈希值不同,则用于在将密码输入数据库之前对密码进行哈希处理的方法必须不同于_userManager.PasswordHasher.HashPassword Can't really think of any other explanation. 真的想不出任何其他解释。 See if you are able to match the two ways of hashing. 查看您是否能够匹配两种哈希方式。

I also encountered this problem, it was caused because the Hashing that was being made in the MVC project got manipulated by the SQL Database in some way, so this way (below) is how I managed to work around the issue of having a miss match in hashed password when comparing entered password and comparing to existing password in SQL Database. 我也遇到了这个问题,这是由于在MVC项目中进行的哈希处理被SQL数据库以某种方式操纵的,所以这种方式(以下)是我设法解决匹配丢失问题的方法。比较输入的密码并与SQL数据库中的现有密码进行比较时,使用哈希密码。

You could try a slightly different way of comparing the entered password with the existing password. 您可以尝试将输入的密码与现有密码进行比较的稍微不同的方法。

public ActionResult Login(UserLogin login)
{

  var v = dc.Users.Where(a => a.UserEmailAddress == login.UserEmailAddress).FirstOrDefault();

  if(string.Compare(Crypto.Hash(login.UserPassword), v.UserPassword) == 0)
  {
     //do login here
  }
}

So if you have your controller set up to accept the login details from the form, you will be able to use the "login" to find the User in the database that you are trying to log in. With this User being found in the query, u can then proceed to perform the "string.Compare" 因此,如果您已将控制器设置为接受来自表单的登录详细信息,则可以使用“登录”在您尝试登录的数据库中找到该用户。在查询中找到该用户,然后您可以继续执行“ string.Compare”

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM