Decrypt Laravel Reset Token Password

I am writing a test that ensures that my reset password function works. The reset password system was created using the php artisan make:auth . To complete the test pass, I need to automate the GET request to /password/reset/{$token} , where $token is the value stored in the password_resets table. Laravel stores the token as follows:

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

but when Laravel sends the user a reset password, the reset token looks like this:

382aa64567ecd05a774c2e4ebb199d3340a1424300707053354c749c10487594 .

My GET request to /password/reset/$2y$10$9grKb3c6.Toiv0kjUWbCUeT8Q8D.Fg2gZ/xDLGQUAkmdyHigmRkNW crashes due to a slash in the reset token. (Right after "g2gZ")

I tried to use the decrypt() helper function, but no luck.

How can I convert the reset token that I pull from the password_resets table to match what Laravel sends to the user?

Not sure if this is relevant, but I updated my application from 5.3 to 5.4.

+5
source share
4 answers

You can get the token from the closure used for additional checks passed to the Notification assertSentTo method, since $token is a public standard for the standard ResetPassword notification.

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); 
+7
source

The token stored in the password_resets table is hashed in the same way as a regular password, so you cannot cancel it to get the original token.

I suggest you use the log mail driver when running tests. Then, the reset password will be printed in text form in the laravel log, and you can extract the token from it.

+2
source

I don’t think you can, the hash that was saved is the encrypted value of the sha256 hash of a random 40-digit number. which means that it cannot be reversible in only one direction.

+1
source

To test the functionality of the reset password, I replace the generated token from the password_reset table with a new one.

The reset current is created using the createTokenRepository() method - laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php

To hash the created token, Laravel uses the make() method - 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
source

Source: https://habr.com/ru/post/1263362/


All Articles