I’m currently working on my Laravel app and to prevent spam I decided that only active users are able to login.
I’m currently using Laravel’s login system just like in Laravel’s official website tutorial, here’s my form action:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}">
This works completely fine, however I’d like to check the user’s active, if not active it would be redirected to the activation page, otherwise it would login.
Is there a simple way to do this or am I obligated to make a new controller, routes and more verifications? Thank you.
Edit: Forgot to mention that I have a ‘active’ column in my database.
Change or override your postLogin()
function in your AuthController
to look like this:
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $this->getCredentials($request);
// This section is the only change
if (Auth::validate($credentials)) {
$user = Auth::getLastAttempted();
if ($user->active) {
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
} else {
return redirect($this->loginPath()) // Change this to redirect elsewhere
->withInput($request->only('email', 'remember'))
->withErrors([
'active' => 'You must be active to login.'
]);
}
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
This code redirects back to the login page with an error message about the user being inactive. If you want to redirect to an authentication page you would change the line I marked with the comment Change this to redirect elsewhere
.
In Laravel 5.4 open Auth/LoginController.php
and add this function:
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
//return $request->only($this->username(), 'password');
return ['email' => $request->{$this->username()}, 'password' => $request->password, 'status' => 1];
}
And you are done..!
This solution is based on Can Celik’s idea and was tested with Laravel 5.3.
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|exists:users,' . $this->username() . ',active,1',
'password' => 'required',
]);
}
The last two comma-separated parameters (active,1
) act as a WHERE clause (WHERE active = '1'
) and can be alternatively written this way:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => [
'required',
Rule::exists('users')->where(function ($query) {
$query->where('active', 1);
}),
],
'password' => 'required'
]);
}
Normally, the validation method only checks if email and password fields are filled out. With the modification above we require that a given email address is found in a DB row with active
value set to 1.
UPDATE:
You can also customize the message:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|exists:users,' . $this->username() . ',active,1',
'password' => 'required',
], [
$this->username() . '.exists' => 'The selected email is invalid or the account has been disabled.'
]);
}
Note that the above message will be shown both when a given email address doesn’t exist or when the account is disabled.
in AuthController override method getCredentials like this:
protected function getCredentials(Request $request) {
$request['active'] = TRUE;
return $request->only($this->loginUsername(), 'password', 'active');
}
make sure you have the column active on user table…
You don’t have to override the whole function. You can just change the Validator in AuthController to achieve that adding “exists:table,column” validation.
Let’s assume that you have a users table with email,password and active fields.
'email' => 'exists:users,email,active,1'
Here is the validotor function should look like in AuthController.php
protected function validator(array $data)
{
return Validator::make($data, [
'email' => 'required|email|max:255|exists:users,email,active,1',
'password' => 'required|confirmed'
]);
}
or if you are using soft deletes this should work too.
'email' => 'exists:users,email,deleted_at,NULL'
You can also check out the validation rule at this link http://laravel.com/docs/5.1/validation#rule-exists