Reputation: 7735
I'm using Laravel 5.4 and its built in Auth API. I've added a column to the users
table called is_admin
. I want to modify the login process so that login only works if is_admin == 1
. I've looked in Illuminate\Foundation\Auth\AuthenticatesUsers.php
(Github) and I could probably make a change there but I'd rather not disturb the core if possible. Is there a more elegant way to do this?
Upvotes: 5
Views: 5126
Reputation: 925
This solution may not be elegant, but still working.
Add this to LoginController
:
protected function authenticated(Request $request, $user)
{
if ( ! $user->is_admin ) {
Auth::logout();
return redirect('login')->withErrors(['is_admin' => 'Only admin users may log in']);
}
}
Then put this in auth/login.blade.php
:
@if($errors->has('is_admin'))
<div class="alert alert-danger" role="alert">{{ $errors->first('is_admin') }}</div>
@endif
Also keep in mind, that you should disable register functionality, because after registering a user still logs in.
Upvotes: 2
Reputation: 7735
I solved this with a solution similar to @Sagar Arora's. In the app\Http\Controllers\Auth\LoginController.php
that is created when you run artisan make:auth
, I overrode the attemptLogin
method from AuthenticatesUsers
. This is the code in LoginController.php
:
protected function attemptLogin(Request $request)
{
return (auth()->attempt(['email' => $request->email, 'password' => $request->password, 'is_admin' => 1]));
}
Now only users with is_admin == 1
will be logged in.
Upvotes: 4
Reputation: 3261
Just like you mentioned, you should never touch the core file. But if you could see laravel has added the AuthenticatesUsers
as trait
on LoginController which means you can simply override it by adding the credentials()
in LoginController like the following.
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return [
'email' => $request->input('email'),
'password' => $request->input('password'),
'is_admin' => 1
];
}
Upvotes: 3
Reputation: 925
I think a better way is to actually allow all users to login. And then limit access via admin
middleware. This way you may apply this middleware to as many routes as you like.
Use it by wrapping necessary routes in
Route::group(['middleware' => 'admin'], function() {
// auth protected routes
});
This way you create app\Http\Middleware\RedirectIfNotAdmin
:
<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfNotAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if ( $user && $user->is_admin ) {
return $next($request);
}
return redirect('/');
}
}
Then in app\Http\Kernel.php
you append it to $routeMiddleware
property:
protected $routeMiddleware = [
// ... other middlewares
'admin' => \App\Http\Middleware\RedirectIfNotAdmin::class
];
Upvotes: 1
Reputation: 1783
You can create your login function as:
So in your login function you can check this by:
if (Auth::attempt(['email' => $email, 'password' => $password, 'is_admin' => 1])) {
// The user is active, not suspended, and exists.
}
You check here manual login process with additional fields:
https://laravel.com/docs/5.4/authentication#authenticating-users Thanks
Upvotes: 1