Я пишу тест, который гарантирует, что функция сброса пароля моего приложения работает. Система сброса пароля была создана с использованием php artisan make:auth
команда. Для того, чтобы пройти тест, мне нужно автоматизировать запрос GET /password/reset/{$token}
где $token
значение хранится в password_resets
Таблица. Laravel хранит токен следующим образом:
$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
но когда Laravel отправляет электронное письмо для сброса пароля пользователю, маркер сброса выглядит в этом письме следующим образом:
382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594
,
Мой запрос GET /password/reset/$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW
происходит сбой из-за косой черты в маркере сброса. (Сразу после «g2gZ»)
Я пытался использовать вспомогательную функцию decrypt()
но не повезло.
Как я могу преобразовать токен сброса пароля, который я извлекаю из password_resets
таблица, соответствующая тому, что Laravel отправляет пользователю?
Не уверен, что это актуально, но я обновил свое приложение с 5.3 до 5.4.
Вы можете получить токен из замыкания, используемый для дополнительных проверок, передаваемых в метод assertSentTo Notification, потому что $token
является публичной собственностью стандарта ResetPassword
уведомление.
В вашем тесте:
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);
Токен, хранящийся в password_resets
Таблица хэшируется как обычный пароль, поэтому вы не можете перевернуть ее, чтобы получить оригинальный токен.
Я предлагаю вам использовать log
почтовый драйвер при запуске тестов. Затем электронное письмо для сброса пароля будет напечатано в виде простого текста в журнале Laravel, и вы можете получить токен из этого.
Я не думаю, что вы можете, хэш, который сохраняется, является зашифрованным значением хэша sha256 случайного 40-значного числа. а это значит, что он необратим, проверяется только одним способом.
Для тестирования функциональности сброса пароля я заменяю сгенерированный токен из password_reset
стол с новым.
Маркер сброса создается с помощью 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]);
}