J'écris un test qui garantit que la fonctionnalité de réinitialisation du mot de passe de mon application fonctionne. Le système de réinitialisation du mot de passe a été créé à l'aide de la commande php artisan make:auth. Pour que le test réussisse, je dois automatiser une requête GET vers /password/reset/{$token}$token est la valeur stockée dans la table password_resets. Laravel stocke le jeton comme ceci:

$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW

Mais lorsque Laravel envoie l'e-mail de réinitialisation du mot de passe à l'utilisateur, le jeton de réinitialisation ressemble à ceci dans l'e-mail:

382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594.

Ma demande GET à /password/reset/$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW échoue en raison de la barre oblique dans le jeton de réinitialisation. ( Juste après le 'g2gZ' )

J'ai essayé d'utiliser la fonction d'assistance decrypt() mais je n'ai pas eu de chance.

Comment puis-je convertir le jeton de réinitialisation du mot de passe que je tire du tableau password_resets pour qu'il corresponde à ce que Laravel envoie à l'utilisateur?

Je ne sais pas si cela est pertinent, mais j'ai mis à niveau mon application de la version 5.3 à la version 5.4.

7
Denis Priebe 26 janv. 2017 à 00:55

4 réponses

Meilleure réponse

Vous pouvez obtenir un jeton de fermeture utilisé pour des vérifications supplémentaires passées à la méthode assertSentTo de Notification car $token est une propriété publique de la notification ResetPassword standard.

Dans votre 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);
12
pinguinjkeke 2 avril 2018 à 10:12

Je ne pense pas que vous le puissiez, le hachage qui est enregistré est une valeur cryptée d'un hachage sha256 d'un nombre aléatoire à 40 chiffres. ce qui signifie qu'il n'est pas réversible, mais vérifiable dans un seul sens.

1
Justin MacArthur 25 janv. 2017 à 22:21

Pour tester la fonctionnalité de réinitialisation du mot de passe, je remplace le jeton généré de la table password_reset par un nouveau.

Le jeton de réinitialisation est créé avec la méthode createTokenRepository() - laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php

Pour le hachage du jeton créé, Laravel utilise la méthode 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]);

}
1
superfly 4 mars 2017 à 10:36

Le jeton stocké dans la table password_resets est haché comme un mot de passe normal, vous ne pouvez donc pas l'inverser pour obtenir le jeton d'origine.

Je vous suggère d'utiliser le log pilote de messagerie lors de l'exécution des tests. Ensuite, l'e-mail de réinitialisation du mot de passe sera imprimé en texte brut dans le journal laravel et vous pourrez récupérer le jeton à partir de là.

3
BrokenBinary 25 janv. 2017 à 22:20