When a user forgets their password and try to reset it, they get a reset password email link with a token:
site.com/my/password/reset/ddc3669ab1bbd78abe620ef910716ae91678bb4beb5cd8896e21efaaa0c9d5c6
On the backend though, the token in the database password_resets table looks like it's hashed:
$2y$10$O6pgU21FhsOcgpgeqR8RReFYoCGhHNBH5bHKxtE6q1tJMTUufrbr.
So when the route is visited, the only piece of identifying information passed is the token:
ddc3669ab1bbd78abe620ef910716ae91678bb4beb5cd8896e21efaaa0c9d5c6
// Controller Method
passwordResetVerifyByToken($token){
$record = DB::table('password_resets')->where('token', $token)
->first();
}
Ofcourse we won't get a record, as the plain token from the email will NOT match the hashed one in the database with the above query. So with the plain emailed token link, when the user clicks it, how can we compare it to the one in the database to verify it exists and is a matching token?
You should use the Hash::check method, which will return true or false depending of if the hash of the reset token matches the stored database value.
if (Hash::check($token, $row->token)) {
// The passwords match...
}
Laravel docs:
https://laravel.com/docs/5.6/hashing#basic-usage
Dont worry Laravel Have there own advanced function Hash you should try this
if (Hash::check($token, $row->token)) {
// write your code or other function
}
Related
by default the password reset token emailed to email is different from one being saved to database. I have used the Hasher::make() and hash_hmac('sha256', $token, env('APP_KEY')) to hash that and then compare that token to database but invain. what should i do to transform emailed token to database token or compare them?
I also tried
public function convertToken($token)
{
if (Str::startsWith($key = env('APP_KEY'), 'base64:')) {
$key = base64_decode(substr($key, 7));
}
return hash_hmac('sha256', $token, $key);
}
The Hasher used by the Laravel default implementation can be retrieved with
$hasher = Password::broker()->getRepository()->getHasher();
You can then hash your token to add them to your database like this :
$hasher->make($token);
And you can check a token against the value stored in your database with this code :
$hasher->check($token, $databaseToken);
But why do you want to implement yourself what Laravel team has already done ? You'd better use Laravel default authentication, unless you do this for fun.
I'm developing a website using Laravel with an existing database.
My User table doesn't have a remember me field. But I want users always login with remember me feature. Can anyone help?
"Remember me" functionality NEEDS a field in DB. Actually you have to store the "remember me" cookie somewhere in your program. Where is a better place than DB to do this??
First you have to add remember_token (100-character string) to your Users table in database which will be used to store the "remember me" token.
In the next step, On your login attemp you must add $remember parameter like this:
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}
after this code, your user will be remembered by his remember cookie. SO he can be remembered like this:
if (Auth::viaRemember()) {
//
}
Anyway, if you want to store the remember_token in another table, you have define a model like RememberToken and add this relationship to your Users model:
public function rememberToken() {
return $this->hasOne('RememberToken'); // also add foreign keys
}
And now some overriding is needed!. First override getRememberToken() and setRememberToken() methods and also you need to override getRememberTokenName().
As a result EloquentUserProvider::retrieveByToken() should be changed in EloquentUserProvider class. You probably have to make your User model to join remember_tokens table on every query by adding global scope to it, and return 'remember_tokens.token' from getRememberTokenName() method.
Is it really necessary by the way?
Is there a way to re-view the accessToken itself after it's been created?
Looking at the code below you can see that $token holds the accessToken for the "Test Token" client and that's fine it works as expected, however, say the user forgot that $token is there a way to display it for the user again?
// user can manually create personal access token
// by using the following
$user = Auth::user();
$token = $user->createToken('Test Token')->accessToken;
// this works fine, however, I want to allow the user to edit / re-view these personal access
// tokens when he/she wants
// I'm able to delete or revoke these tokens but how can I vew the access token again?
// I tried the following:
foreach (Auth::user()->tokens as $token)
{
// but none of these give back that access token??
// halp!
// print "accessToken: " . $token->accessToken;
// print "token: " . $token->token;
}
If I understood correctly: you can store the tokens in DB. If there is more tokens per user you can store it in json format.
I've got an issue when I try to validate the post password via Hash::check in Laravel 5.5
I made a posts table (in this case sales table) with password column. When I try to create the post, it's working perfectly and the password is hashed and also belongs to logged in User. Then on the current post page is a button with an input (password) to delete that specific post, but the condition is always false.
My Controller public function destroy(Request $request, $id)
$input_pass = request('input_password');
$sale = Sale::find($id);
$hashed = $sale->password;
// Check if sale password is correct
if (Hash::check($input_pass, $sale->password)) {
$sale->delete();
} else {
// something else to do
}
For the post store, I used bcrypt method to hash the password. I've been also trying to dd('sale->password') which refers to column in sales table (correct) and dd('$input_pass') which refers to typed in password in DELETE form (also correct) - so I'm a little bit confused, why the pass don't match.
From your comment I find that you have a logical error where you initially hash your password and persist it in DB.
You are passing the string password to bcrypt where it should actually be something like request('password')
Change
'password' => bcrypt('password'),
to
'password' => bcrypt(request('password')),
I am trying to use Laravel's built-in Authentication class. Upon reading it, it seems that it only looks into one table as per the config/auth.php file. As per the doc, I can use syntax like this:
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
My concern is, the email column is in my user table while password is in auth table. As I stated above, my understanding of Laravel's authentication is it only looks for one table only. Did I miss something?
Actually the solution is fantastically simple. You just need to override the getAuthPassword method which is defined in the Authenticatable trait, by adding this to your User model:
public function getAuthPassword()
{
return \DB::table('auth')->where('user_id', $this->id)->pluck('password');
}
And that's it, now the authentication system will get the password from the auth table before checking if it matches with user input.
You can authenticate user manually.
Retrieve user from your user table by email with his password from
auth table (via simple join or eloquent relations).
Validate that password is correct using \Hash::check($password, $hashedPassword); .
Login user manually usingAuth::login($user); if you are using Eloquent or Auth::loginUsingId($id); if simple DB query.
Docs:
Auth http://laravel.com/docs/5.1/authentication#other-authentication-methods
Hash http://laravel.com/docs/5.1/hashing