问题
I'm creating a small app using Laravel 5.3
. I've applied user activation (via email confirmation) on Laravel's default Auth
. But i couldn't find a way to stop sending password reset link if account/user not activated by verifying email address. Currently if a user creates an account and doesn't verify the email address he/she can login using Password Reset link.
this what i've in user table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable();;
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('company')->nullable();;
$table->string('password');
$table->boolean('activated')->default(false);
$table->rememberToken();
$table->timestamps();
});
Schema::create('user_activations', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->string('token')->index();
$table->timestamp('created_at');
});
}
UPDATE I tried to do it by updating the below function. but it's not working
public function reset(Request $request)
{
if (!$request->activated) {
return redirect('/');
} else {
$this->validate($request, $this->rules(), $this->validationErrorMessages());
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->sendResetFailedResponse($request, $response);
}
}
回答1:
I found the solution. Just in case if someone looking for the same solution. Here is the function i overridden
public function sendResetLinkEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$user_check = User::where('email', $request->email)->first();
if (!$user_check->activated) {
return back()->with('status', 'Your account is not activated. Please activate it first.');
} else {
$response = $this->broker()->sendResetLink(
$request->only('email')
);
if ($response === Password::RESET_LINK_SENT) {
return back()->with('status', trans($response));
}
return back()->withErrors(
['email' => trans($response)]
);
}
}
回答2:
Another straightforward way is to create a new validation rule to check if the user account is activated, And then add the rule to the validateEmail
method inside the ForgotPasswordController
. Just make sure that you delete the password token everytime you deactivate a user.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use App\User;
class ActiveUser implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$user = User::whereEmail($value)->first();
if($user) {
if($user->active) {
return true;
}
return false;
}
return true;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'Your account is deactivated.';
}
}
And in the ForgotPasswordController
/**
* Validate the email for the given request.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function validateEmail(Request $request)
{
$this->validate($request, ['email' => [ 'required', 'email', new ActiveUser ]]);
}
And this is how to delete the token at any user deactivation.
$user = \App\user::find(1);
\Illuminate\Support\Facades\Password::broker()->deleteToken($user);
回答3:
Another solution is to overwrite the sendPasswordResetNotification
in your User Model:
/**
* OVERWRITE ORIGINAL
* @param string $token
*/
public function sendPasswordResetNotification($token) {
if(!$this->active){
session()->flash('error', 'Your account is disabled.');
return back();
}
$this->notify(new \Illuminate\Auth\Notifications\ResetPassword($token));
}
If the user is not activated, he won't get another email. Instead, he will be returned back to the login page with an error message in the session. To show it you need something like this in your blade file:
@if ($errors->any())
@foreach ($errors->all() as $message)
<div class="alert alert-danger-plain">
<i class="icon-exclamation"></i> {{ $message }}
</div>
@endforeach
@endif
来源:https://stackoverflow.com/questions/41269684/checking-if-user-is-activated-before-sending-password-reset-email-using-forgot-p