I want to have register / login and send password reset on the same page.
I achieve to have register and login on the same page with different input name. But I don't find a way to add password reset input.
I want to call it "reset_email" but on my controller, if I try :
public function sendResetLinkEmail(Request $request)
{
$this->validateEmail($request);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$request->only('email')
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
/**
* Validate the email for the given request.
*
* #param \Illuminate\Http\Request $request
* #return void
*/
protected function validateEmail(Request $request)
{
$this->validate($request, ['reset_email' => 'required|email']);
}
I've got this error :
We can't find a user with that e-mail address.
Any idea how to use reset_email instead of email for my input name ?
Thank for your help.
Update your method like this:
...
$response = $this->broker()->sendResetLink(
['email' => $request->get('reset_email')]
);
...
This will get your input value and will send it to the password broker with key email, so it will look for users by this column.
Related
The built-in controller for resetting the password Auth \ Reset Password Controller has the reset function
public function reset(Request $request)
{
$request->validate($this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
Well, here we are working with the user and their incoming data. However, I can't understand where the work with the password_resets table (built-in) is going? After all, after password recovery, entries are added/deleted there. I think (maybe incorrectly) that this is implemented in the broker () method, but I can't find it in the hierarchy of traits, interfaces, and other classes.
Checkout /vendor/laravel/framework/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php
This is the default class that implements the TokenRepositoryInterface and is used by the /vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.php.
Inside this class you can find all the actual functionality that handles the password resets including the table operations you mention. For example, one method you'll find is:
/**
* Create a new token record.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
$this->deleteExisting($user);
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken();
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
I have a laravel 5.4 installation and I always used the default Laravel Authentication guard to handle user authentication and, mainly, the password restore process.
Now I had to encrypt the email in the users table using the Elocryptfive library, so I also added email_hash field where the hash of the mail is stored in the db in order to easily retrieve users by their email.
I can easily authenticate users using the hash:
Auth::attempt([
'email_hash' => hash('sha256', $request->get('email')),
'password' => $request->get('password')]
, $remember);
What I can't get working is the password reset process. Is there a class to override in order to retrieve users by email_hash, then access the decrypted email and send the mail, without rewriting the whole password forgotten process?
I found a way to achieve this. I will answer my own question to provide a useful solution if someone else needs some help on the topic:
In your ForgotPasswordController.php, override the sendResetLinkEmail function:
/**
* Send a reset link to the given user.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function sendResetLinkEmail(Request $request)
{
$this->validateEmail($request);
$hashed = hash('sha256', $request->get('email'));
$user = User::where('email_hash', $hashed)->first();
if (!is_null($user)) {
$response = Password::sendResetLink(
['email_hash' => $hashed]
);
} else {
$response = Password::INVALID_USER;
}
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
In your ResetPasswordController.php, override the credentials function:
/**
* Get the password reset credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(Request $request)
{
return [
'email_hash' => hash('sha256', $request->get('email')),
'password' => $request->get('password'),
'password_confirmation' => $request->get('password_confirmation'),
'token' => $request->get('token')
];
}
Thanks to Mike Rodham for pointing out the right direction, I hope it helps someone.
I'm working with laravel Auth. Trying to add new rule with email and password, if status(field in user model) is = 1 then he cannot login. I cannot find where should i add this. I was looking at middleware, guard.php AuthenticateUsers.php but did not found it..
Edit:
I've solved this by creating new middleware that checks for this field. Also it can be done with Auth::attempt
You can try as:
if (Auth::attempt(['email' => $email, 'password' => $password, 'status' => 1])) {
// The user is active, not suspended, and exists.
}
From the Docs
If you wish, you also may add extra conditions to the authentication query in addition to the user's e-mail and password.
Add this code to your LoginController:
/**
* Attempt to log the user with custom credentials into the application.
*
* #param \Illuminate\Http\Request $request
* #return bool
*/
protected function attemptLogin(Request $request)
{
$credentials = $this->credentials($request);
$credentials['status'] = 1; // Additional field you want to check
return $this->guard()->attempt(
$credentials, $request->filled('remember')
);
}
Here we add the status field as a part of checked credentials. If user has status not equal to 1, authentication will fail.
Works with Laravel5.6
I am using built in laravel auth functionality.Its working fine.I am trying to override following two functionality.
1.send forgot password email using mandrill.
2.send verification email while registering account.
Can any one help me to solve this issue
My aim is to use mandril instead of default email
I can see auth built in methods but i didnt got idea how i can override that
trait ResetsPasswords
{
use RedirectsUsers;
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* #param \Illuminate\Http\Request $request
* #param string|null $token
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showResetForm(Request $request, $token = null)
{
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
/**
* Reset the given user's password.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function reset(Request $request)
{
$this->validate($request, $this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->sendResetFailedResponse($request, $response);
}
As answered by Mahfuzal, Laravel comes with a bunch of mail drivers out of the box. So just update your .env file to use the right driver.
As for sending a verification email when creating an account, you just need to override the postRegister() function inside the Auth/AuthController like so:
public function postRegister(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$confirmation_code = str_random(30);
$newUser = new User;
$newUser->username = $request->username;
$newUser->email = $request->email;
$newUser->password = bcrypt($request->password);
$newUser->confirmation_code = $confirmation_code;
$newUser->save();
$data = array('confirmation_code' => $confirmation_code, 'username' => $request->username);
Mail::send('emails.verify', $data, function ($message) use ($newUser){
$message->to($newUser->email, $newUser->username);
$message->subject('Please verify your email address');
});
return redirect('/auth/login');
}
This will execute the above code when registering a user rather than what Laravel does default out of the box so just tweak it to your needs.
You then just need to create a function that will check the token and verify their account when they click the link. For that, I use something similar to what is explained here.
Laravel provides drivers for SMTP, Mailgun, Mandrill, Amazon SES,
PHP's mail function, and sendmail, allowing you to quickly get started
sending mail through a local or cloud based service of your choice.
Open your .env file and change following by your Mandrill credentials and then you're good to go.
MAIL_DRIVER=mandrill
MAIL_HOST=
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
You can create your own reset method in the controller that uses the trait to override the method in the trait.
I'm doing a simple application laravel 5.1, and I want to reset the password for users. I dont have a problem with that.
I just have not found a way to change the path of some files.
Among them is file "password.blade.php" which is what is sent to the user's mail containing the link to the token. This file must be in the Resources / views / emails / route.
Would you like to change: the name and path of the file. ?
Or if you can select a different view to be sent?
Thank you, any information would be appreciated ).
There is an $emailView variable in PasswordBroker.
/**
* The view of the password reset link e-mail.
*
* #var string
*/
protected $emailView;
If you set this to your view in your Password Controller, you should be able to change it's path and name.
If it doesn't work you can overwrite the emailResetLink function in your Password controller and change the view there. Here is the one from Laravel 5.2. You can get 5.1 from your PasswordBroker.php if it's different.
/**
* Send the password reset link via e-mail.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #param string $token
* #param \Closure|null $callback
* #return int
*/
public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->emailView;
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}