web-dev-qa-db-ja.com

Laravelを使用してユーザーがアクティブな場合のみログインする

私は現在、Laravelアプリで作業しており、スパムを防ぐために、アクティブなユーザーのみがログインできると判断しました。私のフォームアクション:

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

これは完全に機能しますが、ユーザーのアクティブを確認したいのですが、アクティブでない場合はアクティベーションページにリダイレクトされ、そうでない場合はログインします。これを行う簡単な方法はありますか、それとも新しいコントローラー、ルート、その他の検証を行う義務がありますか?ありがとうございました。

編集:データベースに「アクティブ」列があることを忘れていました。

22
Micael Sousa

Laravel 5.4/5.5

この関数をLoginControllerに配置して、デフォルトのlogin()関数をオーバーライドします。

_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

AuthControllerpostLogin()関数を次のように変更またはオーバーライドします。

_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_でマークした行を変更します。

54
BrokenBinary

In Laravel 5.4 open 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];
    }

これで完了です。

43
Raja Amer Khan

このソリューションは、Can Celikのアイデアに基づいており、Laravel 5.3。

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

最後の2つのコンマ区切りパラメーター(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に設定されたDB行で特定の電子メールアドレスが検出される必要があります。

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

上記のメッセージは、特定のメールアドレスが存在しない場合、またはアカウントが無効になっている場合に表示されることに注意してください。

14
Mateusz

authControllerで次のようにgetCredentialsメソッドをオーバーライドします。

protected function getCredentials(Request $request) {

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

ユーザーテーブルで列がアクティブになっていることを確認してください...

6
pls13

関数全体をオーバーライドする必要はありません。 AuthControllerのValidatorを変更するだけで、「exists:table、column」検証を追加できます。

メール、パスワード、アクティブなフィールドを含むユーザーテーブルがあると仮定します。

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

または、ソフト削除を使用している場合、これも機能するはずです。

'メール' => 'exists:users、email、deleted_at、NULL'

このリンクで検証ルールを確認することもできます http://laravel.com/docs/5.1/validation#rule-exists

3
Can Celik

ログイン時にajaxリクエストを使用し、カスタムメッセージを取得したい場合、login controllerでこれを実現する方法は次のとおりです。

login()関数

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

Laravel 5.4/5.5の情報を探している人がここに来て、このシナリオ(カスタムメッセージではない)のカスタムメッセージを許可する場合は、 https://laracasts.com/discuss/channels/laravel/user-account-status

'app/Http/Controllers/Auth/LoginController.php`ファイル内の' authenticated 'メソッドをオーバーライドします。

/**
 * 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,
            ]);
    }
}
1
daprezjer

ありがとう@Can_Celik

これは、私が使用していた問題を解決する方法でしたjson response jqueryを使用。

/**
     * Validate the user login request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            'email' => 'required|email|exists:users_table,email,account_status_colunm,active_value',
            'password' => 'required',
        ]);
    }

その後、validation.phpファイルは、これをカスタム検証文字列に追加します

...
'email' => [
        'exists' => 'Account has been disabled. Contact our team.'
    ],

それはすべてです...うまくいきます...

1
The Dead Guy

LoginControllerのsendLoginResponse関数を上書きして、ユーザーがアクティブになっていることを確認します

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
Mohsen

私はLaravelを初めて使用しますが、これは新規参入者も対象としています。私は本当にこれ以上良いことを知らないので、長年の人はこれが悪い習慣である理由を気軽に教えてくれます。

2019年8月24日-Laravel 5.8を使用-これは私の個人的な実装です。

前提条件:

  1. Artisan Make:Authの使用を開始しました
  2. Userテーブルにブール(tinyInt)として「アクティブ」を追加し、関連するモデルなどを更新しました...
  3. 「アクティブ」= 0の場合、ユーザーが標準認証を介してアプリケーションにアクセスできないようにしようとしています。

この場合、LoginControllerをそのままにしておくことができます。

代わりに、「Illuminate/Auth/Middleware/Authenticate.php」を開き、handle()メソッドを次のように置き換えます。

public function handle($request, Closure $next, ...$guards)
    {
        if(!$request->user()->active){
            // either abort with simple 403 access denied page
            // abort(403, "You don't have permissions to access this area");

            // OR force Logout and redirect back to the login page
            return redirect('login')->with($this->auth->logout());
        }

        $this->authenticate($request, $guards);
        return $next($request);
    }

注:Auth :: logout()はここでは機能しませんが、ファイルの上部にあるコンストラクターを介して既に取り込まれています。

public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }

したがって、$ this-> auth-> logout()を使用するだけです。代わりに。

考えてみると、ほとんどすべての基準で「アクティブ」を簡単に交換して、このミドルウェアをまったく同じ方法で更新できます。お役に立てれば!

0
Ryan Tirrell