Laravel 中 Hash::check () 方法 不同環境中,相同雜湊值驗證不透過問題

xiaopi發表於2019-03-22
- 最近公司有個需求:在現有專案中登入功能需要使用另一個專案中的使用者。第一個想到了**oauth2.0** 的**password**模式
- laravel自帶了一個很成熟的擴充套件 **passport**,具體教程很有多,這裡就不說過多
- 為了保證開發速度,我把兩個程式都在本地安裝,並且把兩個程式對應的資料庫都導到了本地

問題一

  • post 請求token,始終提示驗證錯誤,即使用者名稱密碼錯誤。
  • 這是怎麼回事?線上和線下的資料一樣的啊,為什麼線上可以檢查透過,線下檢查不透過呢
  • POST http://xxx/oauth/token
    {
    "grant_type":"password",
    "client_id":"1",
    "client_secret":"zvnbilyiU8hDVAv3RrLfMfw2QRX8zxVOaZnZ2nl6",
    "username":"username",
    "password":"1234561",
    "scope":""
    }
  • 提示
    {
        "error": "invalid_credentials",
        "message": "The user credentials were incorrect."
    }

解決

  • 很明顯,這是使用者名稱密碼驗證不透過
  • 檢視passport 原始碼,勉強看懂一些,在 Laravel\Passport\Bridge\UserRepository 檔案中,getUserEntityByUserCredentials方法中,有如下檢測
if (! $user) {\
  return;\
} elseif (method_exists($user, 'validateForPassportPasswordGrant')) {\
  if (! $user->validateForPassportPasswordGrant($password)) {\
  return;\
  }\
} elseif (! $this->hasher->check($password, $user->getAuthPassword())) {\
  return;\
}

即使用hash::check()方法對傳來的明文password和資料庫中的password雜湊值對比,這裡是不透過的
查閱資料的過程中,發現一篇文件,寫的很好 Laravel底層密碼儲存和驗證實現
最終的我理解的就是如果Hash:make()的沒有指定salt(加鹽),以及cost(工作因子),會使用隨機加鹽和預設的工作因子。
所以我這個問題就是線上伺服器Hash::make()生成的密碼和加了和本地不同的鹽,所以本地用不了。
用本地的環境make一個新的雜湊值,然後儲存到本地資料庫的password中,解決。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章