[英]How to check if entered password is equal to stored password?
假設我已經實現了一種在用戶面板中更改密碼的方法。 在進行更改之前,我要求用戶輸入當前密碼,而我實際上創建了此方法:
[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;
}
本質上,我向該方法發送的username
是唯一字段,並且我可以檢索要求更改密碼的用戶。 我還獲得了新密碼的哈希值,然后將該哈希值與數據庫中存儲的哈希值進行比較。
問題在於哈希是不同的。 我不知道為什么,但是使用相同的密碼,我有兩個不同的哈希值(一個存儲在數據庫中),另一個由該方法動態生成。
也許還有另一種方法來檢查當前密碼是否等於輸入的密碼?
這正是UserManager<TUser>.CheckPasswordAsync(TUser, String)
的用途:
if (await _userManager.CheckPasswordAsync(originalUser, password))
{
// Yes, it's the current password.
}
進行此操作時,最好使用UserManager.FindByNameAsync(String)來獲取originalUser
。 整個功能可能變為:
[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);
}
使用Async
方法需要您的調用代碼使用async/await
,我已將其折疊到上面的示例中。 動作支持開箱即用; 處理Task<T>
的返回類型。
如果您對CheckPasswordAsync
函數的實現方式感興趣,可以在源代碼中自己查看,這可以幫助您確定自己的版本為何不起作用。
如果哈希值不同,則用於在將密碼輸入數據庫之前對密碼進行哈希處理的方法必須不同於_userManager.PasswordHasher.HashPassword
。 真的想不出任何其他解釋。 查看您是否能夠匹配兩種哈希方式。
我也遇到了這個問題,這是由於在MVC項目中進行的哈希處理被SQL數據庫以某種方式操縱的,所以這種方式(以下)是我設法解決匹配丟失問題的方法。比較輸入的密碼並與SQL數據庫中的現有密碼進行比較時,使用哈希密碼。
您可以嘗試將輸入的密碼與現有密碼進行比較的稍微不同的方法。
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
}
}
因此,如果您已將控制器設置為接受來自表單的登錄詳細信息,則可以使用“登錄”在您嘗試登錄的數據庫中找到該用戶。在查詢中找到該用戶,然后您可以繼續執行“ string.Compare”
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.