简体   繁体   中英

Laravel auth to check for column before logging in

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?

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.

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
    ];
}

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

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
    ];

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM