extend laravel 5 built-in authentication to login

2019-03-15 14:16发布

问题:

I use the included authentication of laravel 5.1.6 and want to know how I can extend it, to work like this:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}

If the user is not "active", the login should not be possible. I have an 'active' column in the users table , with 0 or 1 as value. How can i do this while still using the built in authentication with login throtteling.

edit:

I don't have a postLogin function in the AuthController, only a use AuthenticatesAndRegistersUsers, ThrottlesLogins; , a __construct(), a validator() and a create() function. Do I have to change something in the trait in Illuminate\Foundation\Auth\.. or must I add the the postLogin() function in the AuthController ?

回答1:

You can just override the getCredentials() method in your AuthController:

class AuthController extends Controller
{
    use AuthenticatesAndRegistersUsers;

    public function getCredentials($request)
    {
        $credentials = $request->only($this->loginUsername(), 'password');

        return array_add($credentials, 'active', '1');
    }
}

This will add the active = 1 constraint when trying to authenticate a user.

EDIT: If you want a separate error message like BrokenBinary says, then Laravel allows you to define a method called authenticated that is called after a user has been authenticated, but before the redirect, allowing you to do any post-login processing. So you could utilise this by checking if the authenticated user is active, and throw an exception or display an error message if not:

class AuthController extends Controller
{
    use AuthenticatesAndRegistersUsers;

    public function authenticated(Request $request, User $user)
    {
        if ($user->active) {
            return redirect()->intended($this->redirectPath());
        } else {
            // Raise exception, or redirect with error saying account is not active
        }
    }
}

Don’t forget to import the Request class and User model class.



回答2:

I have now changed the auth middleware /app/Http/Middleware/Authenticate.php (added the block below the comment):

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    if ($this->auth->guest())
    {
        if ($request->ajax())
        {
            return response('Unauthorized.', 401);
        }
        else
        {
            return redirect()->guest('auth/login');
        }
    }

    #logout if user not active
    if($this->auth->check() && $this->auth->user()->active !== 1){
        $this->auth->logout();
        return redirect('auth/login')->withErrors('sorry, this user account is deactivated');
    }

    return $next($request);
}

It seems, it also logs out inactive users if they were already logged in.



回答3:

I would add following first thing in postLogin() function.

       $this->validate($request, [
            'email' => 'required|email', 'password' => 'required',
        ]);

        if ($this->auth->validate(['email' => $request->email, 'password' => $request->password, 'active' => 0])) {
            return redirect($this->loginPath())
                ->withInput($request->only('email', 'remember'))
                ->withErrors('Your account is Inactive or not verified');
        }

active is a flag in user table. 0 = Inactive, 1 = active. so whole function would look like following..

public function postLogin(Request $request)
    {
        $this->validate($request, [
            'email' => 'required|email', 'password' => 'required',
        ]);
        if ($this->auth->validate(['email' => $request->email, 'password' => $request->password, 'active' => 0])) {
            return redirect($this->loginPath())
                ->withInput($request->only('email', 'remember'))
                ->withErrors('Your account is Inactive or not verified');
        }
        $credentials  = array('email' => $request->email, 'password' => $request->password);
        if ($this->auth->attempt($credentials, $request->has('remember'))){
                return redirect()->intended($this->redirectPath());
        }
        return redirect($this->loginPath())
            ->withInput($request->only('email', 'remember'))
            ->withErrors([
                'email' => 'Incorrect email address or password',
            ]);
    }


回答4:

Solved: this link ( tutorial) will help you : https://medium.com/@mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810

step1:

add new field to the User table called ‘status’ (1:enabled, 0:disabed)

step2:

to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:

/**
 * Get the needed authorization credentials from the request.
 *
 * @param \Illuminate\Http\Request $request
 * @return array
 */
 protected function credentials(\Illuminate\Http\Request $request)
 {
 $credentials = $request->only($this->username(), ‘password’);

return array_add($credentials, ‘status’, ‘1’);
 }

Step3:

to block the user when using passport authentication ( token ) , in the User.php model add the following function :

public function findForPassport($identifier) {
     return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
     }

Done :)



回答5:

On Laravel 5.3.* update app/Http/Controllers/Auth/LoginController

class LoginController extends Controller
{

    use AuthenticatesUsers;

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(\Illuminate\Http\Request $request)
    {
        $credentials = $request->only($this->username(), 'password');

        return array_add($credentials, 'active', '1');
    }

    // your code here