解密 Laravel 密码重置令牌
Decrypt Laravel Password Reset Token
我正在编写一个测试,以确保我的应用程序的密码重置功能有效。密码重置系统是使用 php artisan make:auth
命令创建的。为了使测试通过,我需要自动向 /password/reset/{$token}
发出 GET 请求,其中 $token
是存储在 password_resets
table 中的值。 Laravel 像这样存储令牌:
ygrKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
但是当 Laravel 向用户发送密码重置电子邮件时,重置令牌在电子邮件中如下所示:
382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594
.
我对 /password/reset/ygrKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
的 GET 请求因重置令牌中的正斜杠而失败。 (在'g2gZ'之后)
我尝试使用辅助函数 decrypt()
但没有成功。
如何转换从 password_resets
table 提取的密码重置令牌以匹配 Laravel 发送给用户的密码?
不确定这是否相关,但我确实将我的应用程序从 5.3 升级到 5.4。
存储在password_resets
table中的令牌就像普通密码一样经过哈希处理,因此您无法通过反转得到原始令牌。
我建议您在 运行 测试时使用 log
mail driver。然后密码重置电子邮件将以纯文本形式打印在 laravel 日志中,您可以从中获取令牌。
我认为你做不到,保存的哈希值是一个随机 40 位数字的 sha256 哈希值的 bcrypted 值。这意味着它是不可逆的,只有一种方式可以检查。
为了测试密码重置功能,我将 password_reset
table 中生成的令牌替换为新令牌。
重置令牌是使用 createTokenRepository()
方法创建的 - laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.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]);
}
您可以从用于传递给 Notification 的 assertSentTo 方法的额外检查的闭包中获取令牌,因为 $token
是标准 ResetPassword
通知的 public 属性。
在你的测试中:
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);
我正在编写一个测试,以确保我的应用程序的密码重置功能有效。密码重置系统是使用 php artisan make:auth
命令创建的。为了使测试通过,我需要自动向 /password/reset/{$token}
发出 GET 请求,其中 $token
是存储在 password_resets
table 中的值。 Laravel 像这样存储令牌:
ygrKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
但是当 Laravel 向用户发送密码重置电子邮件时,重置令牌在电子邮件中如下所示:
382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594
.
我对 /password/reset/ygrKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
的 GET 请求因重置令牌中的正斜杠而失败。 (在'g2gZ'之后)
我尝试使用辅助函数 decrypt()
但没有成功。
如何转换从 password_resets
table 提取的密码重置令牌以匹配 Laravel 发送给用户的密码?
不确定这是否相关,但我确实将我的应用程序从 5.3 升级到 5.4。
存储在password_resets
table中的令牌就像普通密码一样经过哈希处理,因此您无法通过反转得到原始令牌。
我建议您在 运行 测试时使用 log
mail driver。然后密码重置电子邮件将以纯文本形式打印在 laravel 日志中,您可以从中获取令牌。
我认为你做不到,保存的哈希值是一个随机 40 位数字的 sha256 哈希值的 bcrypted 值。这意味着它是不可逆的,只有一种方式可以检查。
为了测试密码重置功能,我将 password_reset
table 中生成的令牌替换为新令牌。
重置令牌是使用 createTokenRepository()
方法创建的 - laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.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]);
}
您可以从用于传递给 Notification 的 assertSentTo 方法的额外检查的闭包中获取令牌,因为 $token
是标准 ResetPassword
通知的 public 属性。
在你的测试中:
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);