Reputation: 333
I'm using laravel's Auth password reset method and not sure i fully understand what part plays the token in all of this.
I'm sending the user an email with Password::remind('[email protected]')
, which generates a token in my password_reminders
table. The token is fully visible in the url.
The user goes to a url that looks something like: mywebsite.com/remindpass/xxxxxx[token]
.
email
and a new password
, sending it trough post to a controller - which uses Password::reset('email','password','xxxxxx')
.The question is how is this secure? What does the generated token do to prevent someone just going to mywebsite.com/remindpass/xxxxxx[token]
and change the email & password as he likes?
Can someone please clarify the proccess?
Upvotes: 2
Views: 228
Reputation: 944546
What does the generated token do to prevent someone just going to
mywebsite.com/remindpass/xxxxxx[token]
and change the email & password as he likes?
Because only you and the person you sent the email to (i.e. the account holder) know what the token is.
A strong implementation will takes steps to make it hard to guess tokens:
/remindpass/*
Upvotes: 1
Reputation: 20980
I'm sure someone could answer this question better than I could.
Short answer:
The token makes it more difficult for someone to guess the credentials needed to reset the password while making the reset link in the email available.
Long answer:
In the file vendor/laravel/framework/src/Illuminate/Auth/Guard.php
, you'll see the method createRememberTokenIfDoesntExist
. This method actually references another method right above it called refreshRememberToken
to set your token.
It uses the laravel helper function str_random
. If you trace this function back to it's source, you'll find it uses the vendor/laravel/framework/src/Illuminate/Support/Str.php
class' random
method.
public static function random($length = 16)
{
if (function_exists('openssl_random_pseudo_bytes'))
{
$bytes = openssl_random_pseudo_bytes($length * 2);
if ($bytes === false)
{
throw new \RuntimeException('Unable to generate random string.');
}
return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
}
return static::quickRandom($length);
}
Now we finally get down to where the token is built. This method uses the function openssl_random_pseudo_bytes
to generate the token. You can read about that function in the PHP manual page for openssl_random_pseudo_bytes, but basically it generates a cryptographically strong random string.
Laravel then takes this string (still in the random method), base 64 encodes it, replaces some characters, and takes a slice of that string based on either the default setting of 16 (seen in the parameter definition $length = 16
) or whatever length is passed into the method by the caller.
So, you get a string that is cryptographically strong and then manipulated as your token.
If you look at the file vendor/laravel/framework/src/Illuminate/Auth/DatabaseUserProvider.php
and find the method retrieveByToken
, you'll see that laravel uses both the user record ID and the token to find the user who's password needs to change.
For someone to guess that string AND the id of you user record that has that token would be incredibly difficult and would require knowledge of your application's business logic.
Upvotes: 3