Вход только в том случае, если пользователь активен с помощью Laravel


В настоящее время я работаю над своим приложением Laravel и для предотвращения спама решил, что только активные пользователи могут входить в систему. В настоящее время я использую систему входа в систему Laravel, как и в учебнике по официальному сайту Laravel, вот мое действие формы:

<form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}">

Это работает полностью нормально, однако я хотел бы проверить активность пользователя, если он не активен, он будет перенаправлен на страницу активации, в противном случае он войдет в систему. Есть ли простой способ сделать это или я обязан создать новый контроллер, маршруты и дополнительные проверки? Спасибо.

Изменить: Забыл упомянуть, что в моей базе данных есть столбец "активный".

Author: BrokenBinary, 2015-06-24

8 answers

Ларавель 5.4/5.5

Переопределите функцию по умолчанию login(), поместив эту функцию в свой LoginController:

public function login(\Illuminate\Http\Request $request) {
    $this->validateLogin($request);

    // If the class is using the ThrottlesLogins trait, we can automatically throttle
    // the login attempts for this application. We'll key this by the username and
    // the IP address of the client making these requests into this application.
    if ($this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);
        return $this->sendLockoutResponse($request);
    }

    // This section is the only change
    if ($this->guard()->validate($this->credentials($request))) {
        $user = $this->guard()->getLastAttempted();

        // Make sure the user is active
        if ($user->active && $this->attemptLogin($request)) {
            // Send the normal successful login response
            return $this->sendLoginResponse($request);
        } else {
            // Increment the failed login attempts and redirect back to the
            // login form with an error message.
            $this->incrementLoginAttempts($request);
            return redirect()
                ->back()
                ->withInput($request->only($this->username(), 'remember'))
                ->withErrors(['active' => 'You must be active to login.']);
        }
    }

    // If the login attempt was unsuccessful we will increment the number of attempts
    // to login and redirect the user back to the login form. Of course, when this
    // user surpasses their maximum number of attempts they will get locked out.
    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}

Переопределение метода login() таким образом рекомендуется по сравнению со многими другими ответами на этот вопрос, поскольку он позволяет вам по-прежнему использовать многие из более продвинутых функций аутентификации Laravel 5.4+, таких как регулирование входа в систему, несколько драйверов/поставщиков защиты аутентификации и т.д. в то же время позволяя вам установить пользовательскую ошибку сообщение.


Ларавель 5.3

Измените или переопределите вашу функцию postLogin() в вашей функции AuthController, чтобы она выглядела следующим образом:

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(),
        ]);

}

Этот код перенаправляет обратно на страницу входа с сообщением об ошибке о том, что пользователь неактивен. Если вы хотите перенаправить на страницу аутентификации, вы должны изменить строку, которую я отметил комментарием Change this to redirect elsewhere.

 37
Author: BrokenBinary, 2017-12-01 20:32:21

В Laravel 5.4 открыто Auth/LoginController.php

И добавьте эту функцию:

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

И вы закончили..!

 35
Author: Raja Amer Khan, 2017-02-25 11:36:02

Это решение основано на идее Кана Челика и было протестировано с помощью Laravel 5.3.

protected function validateLogin(Request $request)
{
    $this->validate($request, [
        $this->username() => 'required|exists:users,' . $this->username() . ',active,1',
        'password' => 'required',
    ]);
}

Последние два параметра, разделенные запятыми (active,1), действуют как предложение WHERE (WHERE active = '1') и могут быть альтернативно записаны следующим образом:

protected function validateLogin(Request $request)
{
    $this->validate($request, [
        $this->username() => [
            'required',
            Rule::exists('users')->where(function ($query) {
                $query->where('active', 1);
            }),
        ],
        'password' => 'required'
    ]);
}

Обычно метод проверки проверяет только заполнение полей электронной почты и пароля. С приведенной выше модификацией мы требуем, чтобы указанный адрес электронной почты был найден в строке базы данных со значением active, равным 1.

ОБНОВЛЕНИЕ (протестировано с Laravel 5.5):

Вы также можете настроить сообщение:

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.'
    ]);
}

Обратите внимание, что приведенное выше сообщение будет отображаться как в том случае, если указанный адрес электронной почты не существует, так и в том случае, если учетная запись отключена.

 11
Author: Mateusz, 2017-12-29 21:21:17

В AuthController переопределите метод getCredentials следующим образом:

protected function getCredentials(Request $request) {

        $request['active'] = TRUE;
        return $request->only($this->loginUsername(), 'password', 'active');
}

Убедитесь, что столбец активен в таблице пользователей...

 6
Author: pls13, 2016-04-02 23:42:10

Вам не нужно переопределять всю функцию целиком. Вы можете просто изменить валидатор в AuthController, чтобы добиться этого, добавив проверку "существует: таблица, столбец".

Предположим, что у вас есть таблица пользователей с электронной почтой, паролем и активными полями.

'email' => 'exists:users,email,active,1'

Вот действительная двигательная функция, которая должна выглядеть так, как в AuthController.php

protected function validator(array $data)
{
    return Validator::make($data, [
        'email' => 'required|email|max:255|exists:users,email,active,1',
        'password' => 'required|confirmed'
    ]);
}

Или, если вы используете мягкое удаление, это тоже должно сработать.

'email' => 'exists:users,email,deleted_at,NULL'

Вы также можете ознакомиться с правилом проверки по этой ссылке http://laravel.com/docs/5.1/validation#rule-exists

 1
Author: Can Celik, 2015-07-17 03:10:06

Я проверяю, активирован ли пользователь с помощью функции перезаписи sendLoginResponse в LoginController

protected function sendLoginResponse(Request $request)
{
    if($this->guard()->user()->active == 0){
        $this->guard()->logout();
        return redirect()->back()
            ->withInput($request->only($this->username(), 'remember'))
            ->withErrors(['active' => 'User in not activated.']);
    }

    $request->session()->regenerate();

    $this->clearLoginAttempts($request);

    return $this->authenticated($request, $this->guard()->user())
            ?: redirect()->intended($this->redirectPath());
}
 1
Author: Mohsen, 2018-02-09 18:27:13

Если кто-то использует ajax-запрос при входе в систему и хочет иметь пользовательское сообщение, вот как я добился этого в контроллере входа:

Функция входа()

  // This section is the only change
    if ($this->guard()->validate($this->credentials($request))) {
        $user = $this->guard()->getLastAttempted();

        // Make sure the user is active
        if ($user->status == 1 && $this->attemptLogin($request)) {
            // Send the normal successful login response
            return $this->sendLoginResponse($request);
        } else {
            // Increment the failed login attempts and redirect back to the
            // login form with an error message.
            $this->incrementLoginAttempts($request);
            return $this->sendFailedLoginResponse($request, true);
        }
    }

И другие функции

 public function sendLoginResponse(Request $request)
{
    $redirectTo = false;
    if ($request->headers->get('referer') == env('APP_URL') . '/' || $request->headers->get('referer') == env('APP_URL') . '/login') {
        $redirectTo = $this->redirectPath();
    }

    if ($request->expectsJson()) {
        return response()->json(['status' => true, 'user' => auth()->user(), 'redirectTo' => $redirectTo, 'fragments' => [
            '#main-nav' => view('includes.nav')->render()
        ]]);
    } else {
        return redirect($redirectTo);
    }
}

public function sendFailedLoginResponse(Request $request, $user_not_active = fasle)
{
    if ($user_not_active) {
        return response()->json(['status' => false, 'email' => 'Your account is not active.']);
    }
    return response()->json(['status' => false, 'email' => 'Incorrect login credentials.']);
}
 1
Author: Piotr Jankiewicz, 2018-02-20 12:39:49

На случай, если кто-то пришел сюда в поисках информации о Laravel 5.4/5.5, и это позволяет создавать пользовательские сообщения только для этого сценария (не комбинированное сообщение) вот ответ на это от https://laracasts.com/discuss/channels/laravel/user-account-status

Переопределите метод "аутентифицированный" в вашем'app/Http/Controllers/Auth/LoginController.php `файл:

/**
 * The user has been authenticated.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $user
 * @return mixed
 */
protected function authenticated(Request $request, $user)
{
    if ($user->status_id == 2) { // or whatever status column name and value indicates a blocked user

        $message = 'Some message about status';

        // Log the user out.
        $this->logout($request);

        // Return them to the log in form.
        return redirect()->back()
            ->withInput($request->only($this->username(), 'remember'))
            ->withErrors([
                // This is where we are providing the error message.
                $this->username() => $message,
            ]);
    }
}
 0
Author: daprezjer, 2017-12-01 18:42:06