Maison > Questions et réponses > le corps du texte
J'ai passé quelques jours à résoudre certains échecs de validation de mot de passe dans Laravel 9. Mot de passe testperson
解析为哈希值 yxc/wAmNCKV.YhpWOfyNoetCj/r3Fs5TyAskgZuIF/LEItWfm7rPW
. Une requête directe de la table de base de données correspondante confirme qu'il s'agit de la valeur de hachage correcte. Cependant l'infrastructure d'authentification de Laravel rejette ce mot de passe et refuse l'authentification.
Ce n'est pas courant. J'ai plusieurs mots de passe qui sont analysés correctement. Par exemple, le mot de passe eo
解析为 y$uNWYvMVmagIwQ2eXnVKLCOAK1QFQdcRtxbvlghf.Xpg0U1w.N./N2
, et Laravel vérifiera ce mot de passe. Le même mécanisme crée les deux enregistrements utilisateur, bien qu'ils disposent d'autorisations différentes (indiquées par la valeur booléenne sur l'enregistrement).
J'ai trouvé un bug dans une fonction password_verify
qui a été identifiée comme renvoyant des faux négatifs dans cette question Stack Overflow et ce fil de discussion Treehouse.
Plus précisément, c'est la pile dans Laravel où ce point d'échec se produit :
login
路由通过控制器类调用 IlluminateFoundationAuthAuthenticatesUsers::login
. login
方法调用 IlluminateFoundationAuthAuthenticatesUsers::attemptLogin
. attemptLogin
方法调用控制器守卫对象的 attempt
Méthode. IlluminateAuthSessionGuard::attempt
调用 IlluminateAuthSessionGuard::hasValidCredentials
. IlluminateAuthSessionGuard::hasValidCredentials
调用守卫提供者对象上的 validateCredentials
Méthode. IlluminateAuthEloquentUserProvider::validateCredentials
在其 hasher 对象上调用 check
Méthode. IlluminateHashingHashManager::check
在其驱动程序上调用 check
Méthode. IlluminateHashingBcryptHasher::check
调用 IlluminateHashingAbstractHasher::check
. IlluminateHashingAbstractHasher::check
appelle IlluminateHashingAbstractHasher::check
调用 password_verify
. Après avoir développé la pile entière, j'exécute le code suivant dans la méthode login
du contrôleur de connexion :
$provider = $this->guard()->getProvider(); $credentials = $this->credentials($request); $user = $provider->retrieveByCredentials($credentials); $password_unhashed = $request['password']; $password_hashed = $user->getAuthPassword(); $password_verify = password_verify($password_unhashed, $password_hashed); logger('attemping login', compact('password_verify','password_unhashed','password_hashed'));
Vider ce contexte :
{ "password_verify": false, "password_unhashed": "testperson", "password_hashed": "yxc/wAmNCKV.YhpWOfyNoetCj/r3Fs5TyAskgZuIF/LEItWfm7rPW" }
Si je mets ce mot de passe dans la requête SELECT users WHERE password=
, j'obtiens l'utilisateur que j'attends.
Que se passe-t-il ? Comment puis-je résoudre ce problème?
P粉4640820612024-03-29 11:37:34
Je pense que votre affirmation selon laquelle le hachage que vous avez fourni est le hachage de la « personne test » est en fait fausse. Puisque les hachages sont à sens unique, je ne peux pas vous dire d'où vient le hachage affiché. REMARQUE : cela fonctionne sur PHP 7.4, mais je ne pense pas que cela fonctionnera sur PHP 8 et supérieur car l'option salt dans passwd_hash() est obsolète.
10, "salt" => substr($testhash, 7, 22)); $pwhash = password_hash($password, PASSWORD_BCRYPT, $options); echo $pwhash."\n"; $salt = substr($pwhash, 0, 29); echo $salt."\n"; $cryptpw = crypt($password, $salt); echo $cryptpw."\n"; if (password_verify($password, $cryptpw)) { echo("Verified.\n"); } else { echo("NOT Verified.\n"); } if (password_needs_rehash($cryptpw, PASSWORD_BCRYPT, $options)) { echo("Needs rehash.\n"); } else { echo("Doesn't need rehash.\n"); } /* testperson results... yxc/wAmNCKV.YhpWOfyNoeVNPMEcYrxepQeFAssFoAaIYs4WLmgZO yxc/wAmNCKV.YhpWOfyNoe yxc/wAmNCKV.YhpWOfyNoeVNPMEcYrxepQeFAssFoAaIYs4WLmgZO Verified. Doesn't need rehash. eo results... y$uNWYvMVmagIwQ2eXnVKLCOAK1QFQdcRtxbvlghf.Xpg0U1w.N./N2 y$uNWYvMVmagIwQ2eXnVKLCO y$uNWYvMVmagIwQ2eXnVKLCOAK1QFQdcRtxbvlghf.Xpg0U1w.N./N2 Verified. Doesn't need rehash. */ ?>