it-swarm.com.de

Melden Sie sich nur an, wenn der Benutzer mit Laravel aktiv ist

Ich arbeite gerade an meiner Laravel-App. Um Spam zu verhindern, habe ich mich dazu entschlossen, dass sich nur aktive Benutzer anmelden können .. __ Ich verwende derzeit das Login-System von Laravel, genau wie in Laravel's offiziellem Website-Tutorial.

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

Dies funktioniert völlig in Ordnung, aber ich möchte den aktiven Benutzer überprüfen, falls nicht aktiv, würde er zur Aktivierungsseite weitergeleitet werden, sonst würde er sich einloggen .. Gibt es eine einfache Möglichkeit, dies zu tun, oder bin ich dazu verpflichtet? ein neuer Controller, Routen und weitere Überprüfungen? Vielen Dank.

Bearbeiten: Ich habe vergessen zu erwähnen, dass sich in meiner Datenbank eine "aktive" Spalte befindet.

17
Micael Sousa

Laravel 5,4/5,5

Überschreiben Sie die Standardfunktion login(), indem Sie diese Funktion in Ihre LoginController einfügen:

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

Das Überschreiben der login()-Methode auf diese Weise wird für viele der anderen Antworten auf diese Frage empfohlen, da Sie damit auch die weiterentwickelten Authentifizierungsfunktionen von Laravel 5.4 und höher verwenden können, z. Sie können jedoch weiterhin eine benutzerdefinierte Fehlermeldung festlegen.


Laravel 5.3

Ändern oder überschreiben Sie Ihre postLogin()-Funktion in Ihrem AuthController, um folgendermaßen auszusehen:

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

}

Dieser Code leitet zurück zur Anmeldeseite mit einer Fehlermeldung, dass der Benutzer inaktiv ist. Wenn Sie auf eine Authentifizierungsseite umleiten möchten, ändern Sie die Zeile, die ich mit dem Kommentar Change this to redirect elsewhere markiert habe.

46
BrokenBinary

Öffnen Sie in Laravel 5.4 Auth/LoginController.php

und füge diese Funktion hinzu:

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

Und du bist fertig ..!

36
Raja Amer Khan

Diese Lösung basiert auf der Idee von Can Celik und wurde mit Laravel 5.3 getestet.

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

Die letzten beiden durch Kommas getrennten Parameter (active,1) fungieren als WHERE-Klausel (WHERE active = '1') und können alternativ folgendermaßen geschrieben werden:

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

Normalerweise prüft die Validierungsmethode nur, ob E-Mail- und Kennwortfelder ausgefüllt sind. Bei der obigen Änderung wird vorausgesetzt, dass sich eine bestimmte E-Mail-Adresse in einer DB-Zeile befindet, deren Wert active auf 1 gesetzt ist.

UPDATE (getestet mit Laravel 5.5):

Sie können die Nachricht auch anpassen:

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

Beachten Sie, dass die obige Nachricht sowohl angezeigt wird, wenn eine bestimmte E-Mail-Adresse nicht existiert, als auch wenn das Konto deaktiviert ist.

13
Mateusz

Überschreiben Sie in AuthController die Methode getCredentials wie folgt:

protected function getCredentials(Request $request) {

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

stellen Sie sicher, dass die Spalte in der Benutzertabelle aktiv ist ...

6
pls13

Sie müssen die gesamte Funktion nicht überschreiben. Sie können den Validator in AuthController einfach ändern, um die Validierung "Vorhanden: Tabelle, Spalte" hinzuzufügen.

Nehmen wir an, Sie haben eine Benutzertabelle mit E-Mail-Adresse, Kennwort und aktiven Feldern.

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

oder wenn Sie weiche Löschungen verwenden, sollte dies ebenfalls funktionieren.

'email' => 'existiert: Benutzer, email, deleted_at, NULL'

Sie können die Validierungsregel auch über diesen Link auschecken http://laravel.com/docs/5.1/validation#rule-exists

3
Can Celik

Wenn jemand beim Login eine Ajax-Anfrage verwendet und eine benutzerdefinierte Nachricht haben möchte, habe ich dies in login controller erreicht:

login () Funktion

  // 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);
        }
    }

Und andere Funktionen

 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

Ich überprüfe, ob der Benutzer durch das Überschreiben der sendLoginResponse-Funktion in LoginController aktiviert wird

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

Falls hier jemand nach Informationen zu Laravel 5.4/5.5 gesucht hat und dies eine benutzerdefinierte Nachricht nur für dieses Szenario ermöglicht (keine kombinierte Nachricht), finden Sie hier die Antwort von https://laracasts.com/discuss/ Channels/Laravel/Benutzerkonto-Status

Überschreiben Sie die "authentifizierte" Methode in Ihrer Datei "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
daprezjer

Danke @Can_Celik

so konnte ich mein Problem lösen, da ich json response mit Jquery verwendete.

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

fügen Sie dies in der Datei validation.php zu Ihren benutzerdefinierten Validierungszeichenfolgen hinzu

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

das ist alles ... funktioniert gut ...

0
The Dead Guy

Ich bin neu in Laravel und dies richtet sich auch an Neuankömmlinge. Langzeiter können mir gerne sagen, warum dies eine schlechte Praxis ist, da ich es noch nicht besser weiß.

Stand 24. August 2019 - mit Laravel 5.8 - Dies ist meine persönliche Implementierung.

Annahmen gemacht:

  1. Sie haben mit Artisan Make: Auth begonnen
  2. Sie haben 'active' als Bool (tinyInt) zu Ihrer Benutzertabelle hinzugefügt und die relevanten Modelle usw. aktualisiert.
  3. Sie versuchen zu verhindern, dass Benutzer über die Standardauthentifizierung Zugriff auf Ihre Anwendung erhalten, wenn: 'active' = 0.

In diesem Fall können Sie Ihren LoginController in Ruhe lassen.

Öffnen Sie stattdessen "Illuminate/Auth/Middleware/Authenticate.php" und ersetzen Sie die handle () -Methode durch:

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

Hinweis: Auth :: logout () funktioniert hier nicht, wird jedoch bereits über den Konstruktor oben in der Datei abgerufen.

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

Sie können also einfach $ this-> auth-> logout () verwenden. stattdessen.

Denken Sie darüber nach - Sie können ganz einfach "Aktiv" für so ziemlich alle Kriterien austauschen und diese Middleware auf die gleiche Weise aktualisieren! Hoffe das hilft!

0
Ryan Tirrell