Laravel leitet nach dem Login zurück zum ursprünglichen Ziel

188

Dies scheint ein ziemlich grundlegender Ablauf zu sein und Laravelhat so viele nette Lösungen für grundlegende Dinge, dass ich das Gefühl habe, etwas zu vermissen.

Ein Benutzer klickt auf einen Link, für den eine Authentifizierung erforderlich ist. Der Authentifizierungsfilter von Laravel wird aktiviert und an eine Anmeldeseite weitergeleitet. Der Benutzer meldet sich an und wechselt dann zu der Originalseite, zu der er gelangen wollte, bevor der Filter "auth" aktiviert wurde.

Gibt es eine gute Möglichkeit zu wissen, auf welche Seite sie ursprünglich zugreifen wollten? Da Laravel die Anfrage abfängt, wusste ich nicht, ob sie irgendwo nachverfolgt wird, um das Routing zu vereinfachen, nachdem sich der Benutzer angemeldet hat.

Wenn nicht, wäre ich gespannt, wie einige von Ihnen dies manuell implementiert haben.

JOV
quelle

Antworten:

234

Für Laravel 5.3 und höher

Überprüfen Sie Scotts Antwort unten.

Für Laravel 5 bis 5.2

Einfach gesagt,

Auf Auth Middleware:

// redirect the user to "/login"
// and stores the url being accessed on session
if (Auth::guest()) {
    return redirect()->guest('login');
}
return $next($request);

Bei der Anmeldeaktion:

// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('defaultpage');
}

Für Laravel 4 (alte Antwort)

Zum Zeitpunkt dieser Antwort gab es keine offizielle Unterstützung durch das Framework selbst. Heutzutage können Sie verwendendie Methode, auf die bgdrl unten hinweistdiese Methode: (Ich habe versucht, seine Antwort zu aktualisieren, aber es scheint, dass er nicht akzeptiert)

Beim Authentifizierungsfilter:

// redirect the user to "/login"
// and stores the url being accessed on session
Route::filter('auth', function() {
    if (Auth::guest()) {
        return Redirect::guest('login');
    }
});

Bei der Anmeldeaktion:

// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return Redirect::intended('defaultpage');
}

Für Laravel 3 (noch ältere Antwort)

Sie könnten es so implementieren:

Route::filter('auth', function() {
    // If there's no user authenticated session
    if (Auth::guest()) {
        // Stores current url on session and redirect to login page
        Session::put('redirect', URL::full());
        return Redirect::to('/login');
    }
    if ($redirect = Session::get('redirect')) {
        Session::forget('redirect');
        return Redirect::to($redirect);
    }
});
// on controller
public function get_login()
{
    $this->layout->nest('content', 'auth.login'); 
}

public function post_login()
{
    $credentials = [
        'username' => Input::get('email'),
        'password' => Input::get('password')
    ];

    if (Auth::attempt($credentials)) {
        return Redirect::to('logged_in_homepage_here');
    }

    return Redirect::to('login')->with_input();
}

Das Speichern der Umleitung in einer Sitzung hat den Vorteil, dass sie auch dann beibehalten wird, wenn der Benutzer seine Anmeldeinformationen falsch eingegeben hat oder kein Konto hat und sich anmelden muss.

Dies ermöglicht auch, dass alles andere als Auth eine Umleitung für die Sitzung festlegt, und es funktioniert auf magische Weise.

vFragosop
quelle
Wäre es nicht sinnvoller, zur Sitzung zu blinken, als sie zu setzen und zu vergessen? Ihre Anmeldeaktion würde nur eine Umleitung auf den Wert in der Sitzung zurückgeben, falls vorhanden, oder auf die andere Standardseite.
Bilalq
2
Ich habe die Antwort bearbeitet, um zu erklären, warum dies besser ist als Flash.
vFragosop
Das macht Sinn. Besser als jedes Mal neu zu blinken.
Bilalq
1
Wenn Auth :: try () erfolgreich ist, können Sie den Benutzer einfach auf die Standardseite (normalerweise seine Startseite) umleiten. Diese Umleitung durchläuft diesen Filter erneut und leitet ihn zur ursprünglich angeforderten URL weiter, falls vorhanden. Andernfalls wird es einfach weiter sein Zuhause rendern. Ich werde ein Beispiel für eine Anmeldeaktion setzen.
vFragosop
1
in 5.1 ist es in der Middleware RedirectIfAuthenticated.php: if ($ this-> auth-> check ()) {return redirect ('/ privatepage'); }
Dave Driesmans
72

Laravel> = 5,3

Die Auth-Änderungen in 5.3 erleichtern die Implementierung etwas und unterscheiden sich geringfügig von 5.2, da die Auth-Middleware in den Service-Container verschoben wurde.

Ändern Sie den neuen Middleware-Authentifizierungs-Redirector

/app/Http/Middleware/RedirectIfAuthenticated.php

Ändern Sie die Grifffunktion geringfügig, damit Folgendes aussieht:

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        return redirect()->intended('/home');
    }

    return $next($request);
}

TL; DR Erklärung

Der einzige Unterschied besteht in der 4. Zeile; Standardmäßig sieht es so aus:

return redirect("/home");

Da Laravel> = 5.3 beim Überprüfen des Auth Guard automatisch die letzte "beabsichtigte" Route speichert, ändert sich diese in:

return redirect()->intended('/home');

Das weist Laravel an, vor dem Anmelden zur zuletzt vorgesehenen Seite umzuleiten, andernfalls gehen Sie zu "/ home" oder wohin Sie sie standardmäßig senden möchten.

Ich hoffe, das hilft jemand anderem - es gibt nicht viel über die Unterschiede zwischen 5.2 und 5.3, und insbesondere in diesem Bereich gibt es einige.

Scott Byers
quelle
1
für Laravel 6.4 funktioniert das nicht mehr ... irgendeine Idee bitte?
Alex Toader
Ich würde verwenden return redirect()->intended(RouteServiceProvider::HOME);, um Ihren Heimweg an einem Ort zu halten.
Mateusz
26

Ich habe diese beiden großartigen Methoden gefunden, die für Sie äußerst hilfreich sein könnten.

Redirect::guest();
Redirect::intended();

Sie können diesen Filter auf die Routen anwenden, die authentifiziert werden müssen.

Route::filter('auth', function()
{
    if (Auth::guest()) {
           return Redirect::guest('login');
    }
});

Diese Methode dient im Wesentlichen dazu, die Seite zu speichern, die Sie besuchen wollten, und leitet Sie zur Anmeldeseite weiter .

Wenn der Benutzer authentifiziert ist, können Sie anrufen

return Redirect::intended();

und es leitet Sie zu der Seite weiter, die Sie zuerst erreichen wollten.

Es ist eine großartige Möglichkeit, dies zu tun, obwohl ich normalerweise die folgende Methode verwende.

Redirect::back()

Sie können diesen fantastischen Blog überprüfen .

giannis christofakis
quelle
Dies ist viel besser als die oben genannten Lösungen. Die obigen Lösungen setzen voraus, dass die Anmeldefunktion geschlossen werden kann, was mit 4.1 nicht möglich war. Aber das war viel einfacher und funktionierte so wie es ist.
user2662680
20

Sie können die Funktion Redirect :: beabsichtigte verwenden. Der Benutzer wird zu der URL umgeleitet, auf die er zugreifen wollte, bevor er vom Authentifizierungsfilter abgefangen wird. Für diese Methode kann ein Fallback-URI angegeben werden, falls das beabsichtigte Ziel nicht verfügbar ist.

In der Post Login / Register:

return Redirect::intended('defaultpageafterlogin');
Dabuno
quelle
11

Ich benutze dies seit einer Weile für meinen Sprachauswahlcode. Solange Sie nur 1 Seite zurückgehen müssen, funktioniert es einwandfrei:

return Redirect::to(URL::previous());

Es ist nicht die leistungsstärkste Lösung, aber es ist super einfach und kann helfen, ein paar Rätsel zu lösen. :) :)

Federico Stango
quelle
5
Ja, vorheriges () funktioniert gut. Wenn Ihr erster Anmeldevorgang jedoch fehlschlägt (die Seite "Anmeldung fehlgeschlagen" wird zu Ihrer vorherigen Seite) und der zweite Anmeldevorgang erfolgreich ist, werden Sie erneut zur Anmeldeseite weitergeleitet (wodurch Sie möglicherweise zur Startseite weitergeleitet werden).
Shriganesh Shintre
11

Ändern Sie Ihren LoginControllers-Konstruktor in:

public function __construct()
    {
        session(['url.intended' => url()->previous()]);
        $this->redirectTo = session()->get('url.intended');

        $this->middleware('guest')->except('logout');
    }

Sie werden vor der Anmeldeseite (2 Seiten zurück) zur Seite zurückgeleitet.

MevlütÖzdemir
quelle
Der einzige, der für mich funktioniert. Es muss bedeuten, dass irgendwo eine weitere Weiterleitung stattfindet, aber wer weiß wo.
Arthur Tarasov
8
return Redirect::intended('/');

Dadurch werden Sie zur Standardseite Ihres Projekts weitergeleitet, dh zur Startseite.

Parag Bhingre
quelle
6

Für Laravel 5. * versuchen Sie diese.

return redirect()->intended('/');

oder

return Redirect::intended('/');
Nuruzzaman Milon
quelle
5

Laravel 3

Ich habe Ihren Code (Vinícius Fragoso Pinheiro) leicht angepasst und Folgendes in filter.php eingefügt

Route::filter('auth', function()
{
    // If there's no user authenticated session
    if (Auth::guest()) {
        // Flash current url to session and redirect to login page
        Session::flash('redirect', URL::full());
        return Redirect::guest('login');
    }
});

Und dann in meiner AuthController.php:

// Try to log the user in.
if (Auth::attempt($userdata)) {

    if ($redirect = Session::get('redirect')) {
        return Redirect::to($redirect);
    } else {
        // Redirect to homepage
        return Redirect::to('your_default_logged_in_page')->with('success', 'You have logged in successfully');
    }
} else {
    // Reflash the session data in case we are in the middle of a redirect 
    Session::reflash('redirect');

    // Redirect to the login page.
    return Redirect::to('login')->withErrors(['password' => 'Password invalid'])->withInput(Input::except('password'));
}

Beachten Sie, dass die 'redirect' Sitzungsdaten erneut aktualisiert werden, wenn ein Authentifizierungsproblem vorliegt. Dadurch bleibt die Umleitung bei Anmeldefehlern erhalten. Sollte der Benutzer jedoch zu irgendeinem Zeitpunkt wegklicken, wird der nächste Anmeldevorgang nicht durch die Sitzungsdaten unterbrochen.

Sie müssen die Daten auch zum Zeitpunkt der Anzeige des Anmeldeformulars in Ihrem erneut flashen AuthController, da sonst die Kette unterbrochen wird:

public function showLogin()
{
    // Reflash the session data in case we are in the middle of a redirect 
    Session::reflash('redirect');

    // Show the login page
    return View::make('auth/login');
}
Joe Richards
quelle
3

Verwenden Redirect;

Dann benutze dies:

return Redirect::back();
ujwal dhakal
quelle
0

Für Laravel 5.5 und wahrscheinlich 5.4

Im App \ Http \ Middleware \ RedirectIfAuthenticated Änderung redirect('/home')an redirect()->intended('/home')im Griff Funktion:

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        return redirect()->intended('/home');
    }

    return $next($request);
}

Erstellen Sie in App \ Http \ Controllers \ Auth \ LoginController die showLoginForm()Funktion wie folgt:

public function showLoginForm()
{
    if(!session()->has('url.intended'))
    {
        session(['url.intended' => url()->previous()]);
    }
    return view('auth.login');
}

Auf diese Weise wird eine andere Seite umgeleitet, wenn sie beabsichtigt ist, andernfalls wird sie nach Hause umgeleitet.

DerDare
quelle
0

Ich verwende den folgenden Ansatz mit einem benutzerdefinierten Login-Controller und Middleware für Laravel 5.7, hoffe jedoch, dass dies in jeder der Laravel 5-Versionen funktioniert

  • in der Middleware

    if (Auth::check()){
        return $next($request);
    }
    else{
      return redirect()->guest(route('login'));
    }
  • Anmeldemethode innerhalb des Controllers

    if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('/default');
    }
  • Wenn Sie die beabsichtigte URL an die Clientseite übergeben müssen , können Sie Folgendes versuchen

       if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
           $intended_url= redirect()->intended('/default')->getTargetUrl();
           $response = array(
          'status' => 'success',
          'redirectUrl' => $intended_url,
          'message' => 'Login successful.you will be redirected to home..', );
          return response()->json($response);
        } else {
            $response = array(
          'status' => 'failed',
          'message' => 'username or password is incorrect', );
         return response()->json($response);
        }
Nayeem Azad
quelle
0

Zunächst sollten Sie wissen, wie Sie den Benutzer zur Anmelderoute umleiten:

return redirect()->guest('/signin');

So nicht:

return redirect()->intended('/signin');
Odilov Oybek
quelle
0

Laravel unterstützt diese Funktion jetzt sofort! (Ich glaube seit 5.5 oder früher).

Fügen Sie eine __construct()Methode zu Ihrer hinzu, Controllerwie unten gezeigt:

public function __construct()
{
    $this->middleware('auth');
}

Nach der Anmeldung werden Ihre Benutzer zu der Seite weitergeleitet, die sie ursprünglich besuchen wollten.

Sie können auch die E-Mail-Überprüfungsfunktion von Laravel hinzufügen, wie es Ihre Anwendungslogik erfordert:

public function __construct()
{
    $this->middleware(['auth', 'verified']);
}

Die Dokumentation enthält ein sehr kurzes Beispiel:

Sie können auch mithilfe von except oder onlyOptionen auswählen, auf welche Controller-Methoden die Middleware angewendet wird.

Beispiel mit except:

public function __construct()
{
    $this->middleware('auth', ['except' => ['index', 'show']]);
}

Beispiel mit only:

public function __construct()
{
    $this->middleware('auth', ['only' => ['index', 'show']]);
}

Weitere Informationen zu exceptund onlyMiddleware-Optionen:

LobsterBaz
quelle
0

Wenn Sie Axios oder eine andere AJAX-Javascript-Bibliothek verwenden, möchten Sie möglicherweise die URL abrufen und an das Front-End übergeben

Sie können dies mit dem folgenden Code tun

   $default = '/';

   $location = $request->session()->pull('url.intended', $default);

    return ['status' => 200, 'location' => $location];

Dies gibt eine json-formatierte Zeichenfolge zurück

Emmanuel David
quelle
0

In Laravel 5.8

Fügen Sie unter App \ Http \ Controllers \ Auth \ LoginController die folgende Methode hinzu

public function showLoginForm()
{
    if(!session()->has('url.intended'))
        {
            session(['url.intended' => url()->previous()]);
        }
    return view('auth.login');
}

Ersetzen Sie in App \ Http \ Middleware \ RedirectIfAuthenticated "return redirect ('/ home');" durch Folgendes

 if (Auth::guard($guard)->check()) 
    {
        return redirect()->intended();
    }
Yann Boyongo
quelle
-1

Haben Sie dies in Ihrer route.php versucht?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','HomeController@index');
});
Arios
quelle
-1
       // Also place this code into base controller in contract function,            because ever controller extends base  controller
 if(Auth::id) {
  //here redirect your code or function
 }
if (Auth::guest()) {
       return Redirect::guest('login');
}
cooler Programmierer
quelle
2
Bitte geben Sie einen Kommentar zu Ihrem Code ein, um einen Kontext bereitzustellen. Vielen Dank
Suever
-1

Hier ist meine Lösung für 5.1. Ich brauchte jemanden, der auf die Schaltfläche "Gefällt mir" in einem Beitrag klickt, zum Anmelden weitergeleitet wird und dann zur ursprünglichen Seite zurückkehrt. Wenn sie bereits angemeldet waren, wird diehref Schaltfläche "Gefällt mir" mit JavaScript abgefangen und in eine AJAX-Anfrage umgewandelt.

Der Knopf ist so etwas wie <a href="https://stackoverflow.com/like/931">Like This Post!</a>. /like/931wird von einem LikeController verwaltet, der die authMiddleware benötigt .

Fügen Sie in der Middleware Authentifizieren (der handle()Funktion) zu Beginn Folgendes hinzu:

    if(!str_contains($request->session()->previousUrl(), "/auth/login")) {
        $request->session()->put('redirectURL', $request->session()->previousUrl());
        $request->session()->save();
    }

Ändern /auth/loginSie die URL für die Anmeldung. Dieser Code speichert die URL der Originalseite in der Sitzung, es sei denn, die URL ist die Anmelde-URL. Dies ist erforderlich, da diese Middleware anscheinend zweimal aufgerufen wird. Ich bin mir nicht sicher warum oder ob das stimmt. Wenn Sie diese Bedingung jedoch nicht überprüfen, entspricht sie der korrekten Originalseite und wird dann irgendwie zu/auth/login . Es gibt wahrscheinlich einen eleganteren Weg, dies zu tun.

Dann in dem LikeControlleroder einem anderen Controller, der die URL für die auf der Originalseite gedrückte Schaltfläche verarbeitet:

//some code here that adds a like to the database
//...
return redirect($request->session()->get('redirectURL'));

Diese Methode ist sehr einfach, erfordert keine Überschreibung vorhandener Funktionen und funktioniert hervorragend. Es ist möglich, dass es für Laravel einen einfacheren Weg gibt, dies zu tun, aber ich bin mir nicht sicher, was es ist. Die Verwendung der intended()Funktion funktioniert in meinem Fall nicht, da der LikeController auch wissen musste, wie die vorherige URL lautete, um darauf zurückzuleiten. Im Wesentlichen zwei Umleitungsebenen nach hinten.

Brynn Bateman
quelle
-1

Für Laravel 5.2 (frühere Versionen habe ich nicht verwendet)

Fügen Sie den Code in die Datei app \ Http \ Controllers \ Auth \ AurhController.php ein

   /**
 * Overrides method in class 'AuthenticatesUsers'
 *
 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 */
public function showLoginForm()
{
    $view = property_exists($this, 'loginView')
        ? $this->loginView : 'auth.authenticate';
    if (view()->exists($view)) {
        return view($view);
    }
    /**
     * seve the previous page in the session
     */
    $previous_url = Session::get('_previous.url');
    $ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
    $ref = rtrim($ref, '/');
    if ($previous_url != url('login')) {
        Session::put('referrer', $ref);
        if ($previous_url == $ref) {
            Session::put('url.intended', $ref);
        }
    }
    /**
     * seve the previous page in the session
     * end
     */
    return view('auth.login');
}
/**
 * Overrides method in class 'AuthenticatesUsers'
 *
 * @param Request $request
 * @param $throttles
 *
 * @return \Illuminate\Http\RedirectResponse
 */
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
    if ($throttles) {
        $this->clearLoginAttempts($request);
    }
    if (method_exists($this, 'authenticated')) {
        return $this->authenticated($request, Auth::guard($this->getGuard())->user());
    }
    /*return to the previous page*/
    return redirect()->intended(Session::pull('referrer'));
    /*return redirect()->intended($this->redirectPath()); /*Larevel default*/
}

Und Namespace importieren: use Session;

Wenn Sie keine Änderungen an der Datei app \ Http \ Controllers \ Auth \ AurhController.php vorgenommen haben, können Sie sie einfach durch die Datei aus dem GitHub ersetzen

zdorovo
quelle
-1

Laravel 5.2

Wenn Sie eine andere Middleware wie die Admin- Middleware verwenden, können Sie eine Sitzung für url.intended festlegen, indem Sie Folgendes verwenden:

Grundsätzlich müssen wir manuell \Session::put('url.intended', \URL::full());für die Umleitung einstellen .

Beispiel

  if (\Auth::guard($guard)->guest()) {
      if ($request->ajax() || $request->wantsJson()) {
         return response('Unauthorized.', 401);
      } else {
        \Session::put('url.intended', \URL::full());
        return redirect('login');
      }
  }

Beim Anmeldeversuch

Stellen Sie sicher, dass Sie beim Anmeldeversuch verwenden return \Redirect::intended('default_path');

Rashedul Islam Sagor
quelle
Dafür redirect()->guest('login')ist es da.
Emile Bergeron
-1

Larvel 5.3 hat bei mir tatsächlich funktioniert, indem ich nur LoginController.php aktualisiert habe

 use Illuminate\Support\Facades\Session;
 use Illuminate\Support\Facades\URL;


public function __construct()
{
    $this->middleware('guest', ['except' => 'logout']);
    Session::set('backUrl', URL::previous());
}


public function redirectTo()
{
    return Session::get('backUrl') ? Session::get('backUrl') :   $this->redirectTo;
}

Ref: https://laracasts.com/discuss/channels/laravel/redirect-to-previous-page-after-login

Nomi
quelle
-1

Für Laravle 5.7 müssen Sie folgende Änderungen vornehmen:

Middleware> RedirectIfAuthenticated.php

Ändere das:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/admin');
        }

        return $next($request);
    }

Dazu:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/yourpath');
        }

        return $next($request);
    }

return redirect ('/ yourpath');

Prinz Ahmed
quelle
Was ist mypath? (Benutzerpass für zurück zu diesem)
Mostafa Norzade