解密 Laravel 密码重置令牌
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41862370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Decrypt Laravel Password Reset Token
提问by Denis Priebe
I am writing a test that ensures that the password reset functionality of my application works. The password reset system was created using the php artisan make:auth
command. In order to make the test pass I need to automate a GET request to /password/reset/{$token}
where $token
is the value stored in the password_resets
table. Laravel stores the token like this:
我正在编写一个测试,以确保我的应用程序的密码重置功能正常工作。密码重置系统是使用该php artisan make:auth
命令创建的。为了使测试通过我需要自动化的GET请求来/password/reset/{$token}
这里$token
是存储在值password_resets
表。Laravel 像这样存储令牌:
$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
but when Laravel sends the password reset email to the user, the reset token looks like this in the email:
但是当 Laravel 向用户发送密码重置邮件时,邮件中的重置令牌如下所示:
382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594
.
382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594
.
My GET request to /password/reset/$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
fails due to the forward slash in the reset token. (Right after the 'g2gZ')
/password/reset/$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
由于重置令牌中的正斜杠,我的 GET 请求失败。(在 'g2gZ' 之后)
I tried using the helper function decrypt()
but had no luck.
我尝试使用辅助函数decrypt()
但没有运气。
How can I convert the password reset token I pull from the password_resets
table to match what Laravel sends to the user?
如何转换我从password_resets
表中提取的密码重置令牌以匹配 Laravel 发送给用户的内容?
Not sure if this is relevant but I did upgrade my application from 5.3 to 5.4.
不确定这是否相关,但我确实将我的应用程序从 5.3 升级到 5.4。
回答by pinguinjkeke
You can get token from closure used for additional checks passed to Notification's assertSentTo method because $token
is a public property of standard ResetPassword
notification.
您可以从用于传递给 Notification 的 assertSentTo 方法的附加检查的闭包中获取令牌,因为它$token
是标准ResetPassword
通知的公共属性。
In your test:
在您的测试中:
Notification::fake();
$this->postJson('api/user/reset', ['email' => $user->email])
->assertStatus(200);
$token = '';
Notification::assertSentTo(
$this->user,
\Illuminate\Auth\Notifications\ResetPassword::class,
function ($notification, $channels) use (&$token) {
$token = $notification->token;
return true;
});
$this->postJson('api/user/resetting', [
'email' => $user->email,
'token' => $token,
'password' => '87538753',
'password_confirmation' => '87538753'
])
->assertStatus(200);
回答by BrokenBinary
The token stored in the password_resets
table is hashed just like a normal password, so you can't reverse it to get the original token.
存储在password_resets
表中的令牌就像普通密码一样经过哈希处理,因此您无法将其反转以获取原始令牌。
I suggest that you use the log
mail driverwhen running tests. Then the password reset email will be printed in plain text in the laravel log and you can grab the token from that.
我建议您在运行测试时使用log
邮件驱动程序。然后密码重置电子邮件将以纯文本形式打印在 laravel 日志中,您可以从中获取令牌。
回答by Justin MacArthur
I don't think you can, the hash that's saved is a bcrypted value of a sha256 hash of a random 40 digit number. which means it's not reversible just one way checkable.
我认为你不能,保存的散列是一个随机 40 位数字的 sha256 散列的 bcrypted 值。这意味着它不是可逆的,只能通过一种方式检查。
回答by superfly
For testing the password reset functionality, I replace the generated token from the password_reset
table with a new one.
为了测试密码重置功能,我将password_reset
表中生成的令牌替换为一个新令牌。
The reset token is created with the createTokenRepository()
method - laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php
使用以下createTokenRepository()
方法创建重置令牌-laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php
For hashing the created token, Laravel uses the make()
method - laravel/framework/src/Illuminate/Hashing/BcryptHasher.php
为了散列创建的令牌,Laravel 使用make()
方法 -laravel/framework/src/Illuminate/Hashing/BcryptHasher.php
public function test_it_should_reset_the_password()
{
Mail::fake();
$user = factory(App\User::class)->create();
$response = $this->json('POST', 'api/password/email',
[
'email' => $user->email
]);
$response->assertStatus(202);
Mail::hasSent($user, ResetPassword::class);
// Since we don't know the emailed token from
// the previous JSON call, we're
// gonna replace the token with a new one
$token = hash_hmac('sha256', Str::random(40), $user);
DB::table('password_resets')
->where('email', $user->email)
->update([
'token' => password_hash($token, PASSWORD_BCRYPT, ['cost' => '10'])
]);
$response = $this->json('POST', 'api/password/reset', [
'email' => $user->email,
'password' => 'new_user_password',
'password_confirmation' => 'new_user_password',
'token' => $token
]);
$response->assertStatus(202);
$response = $this->json('POST', 'api/login',
[
'email' => $user->email,
'password' => 'new_user_password'
]);
$response->assertStatus(202);
// check for JWT token
$response->assertJson(['token' => true]);
}