Laravel reindirizza alla destinazione originale dopo il login


189

Sembra un flusso piuttosto semplice, e Laravelha così tante belle soluzioni per le cose di base, mi sento come se mi mancasse qualcosa.

Un utente fa clic su un collegamento che richiede l'autenticazione. Il filtro di autenticazione di Laravel si avvia e li instrada verso una pagina di accesso. L'utente accede, quindi passa alla pagina originale a cui stava tentando di accedere prima che il filtro "auth" iniziasse.

C'è un buon modo per sapere a quale pagina stavano cercando di accedere in origine? Poiché Laravel è quello che intercetta la richiesta, non sapevo se tiene traccia di un percorso per un facile instradamento dopo che l'utente ha effettuato l'accesso.

Altrimenti, sarei curioso di sapere come alcuni di voi lo hanno implementato manualmente.

Risposte:


234

Per Laravel 5.3 e versioni successive

Controlla la risposta di Scott qui sotto.

Per Laravel 5 fino a 5.2

In poche parole,

Nel middleware auth:

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

All'azione di accesso:

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

Per Laravel 4 (vecchia risposta)

Al momento di questa risposta non vi era alcun sostegno ufficiale dal quadro stesso. Al giorno d'oggi puoi usareil metodo indicato da bgdrl di seguitoquesto metodo: (ho provato ad aggiornare la sua risposta, ma sembra che non accetterà)

Sul filtro di autenticazione:

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

All'azione di accesso:

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

Per Laravel 3 (risposta ancora più vecchia)

Potresti implementarlo in questo modo:

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

La memorizzazione del reindirizzamento su Session ha il vantaggio di persistere anche se l'utente non ha digitato le proprie credenziali o non ha un account e deve registrarsi.

Ciò consente anche a qualsiasi altra cosa oltre a Auth di impostare un reindirizzamento sulla sessione e funzionerà magicamente.


Non avrebbe più senso passare alla sessione piuttosto che mettere e dimenticare? L'azione di accesso restituirebbe semplicemente un reindirizzamento al valore nella sessione se esiste o altrimenti la pagina predefinita.
bilalq,

2
Ho modificato la risposta per spiegare perché questo è meglio di Flash.
vFragosop,

Questo ha senso. Meglio che rifrangere ogni volta.
bilalq,

1
Quando passa Auth :: try (), puoi semplicemente reindirizzare l'utente alla pagina predefinita (di solito la sua casa). Quel reindirizzamento passerà di nuovo attraverso quel filtro e lo reindirizzerà all'URL richiesto originale, se presente. Altrimenti, continuerà semplicemente a rendere la sua casa. Metterò un esempio di azione di accesso.
vFragosop,

1
in 5.1 è nel middleware RedirectIfAuthenticated.php: if ($ this-> auth-> check ()) {return redirect ('/ privatepage'); }
Dave Driesmans,

73

Laravel> = 5.3

Le modifiche di Auth in 5.3 rendono l'implementazione di questo un po 'più semplice e leggermente diversa da 5.2 poiché il Middleware Auth è stato spostato nel contenitore di servizi.

Modifica il nuovo redirector di autenticazione del middleware

/app/Http/Middleware/RedirectIfAuthenticated.php

Cambia leggermente la funzione handle, quindi sembra:

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

    return $next($request);
}

TL; spiegazione DR

L'unica differenza è nella 4a riga; per impostazione predefinita è simile al seguente:

return redirect("/home");

Poiché Laravel> = 5.3 salva automaticamente l'ultima rotta "prevista" durante il controllo di Auth Guard, cambia in:

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

Ciò dice a Laravel di reindirizzare all'ultima pagina prevista prima dell'accesso, altrimenti vai su "/ home" o ovunque tu voglia inviarli per impostazione predefinita.

Spero che questo aiuti qualcun altro - non c'è molto là fuori sulle differenze tra 5.2 e 5.3, e in quest'area in particolare ce ne sono alcune.


2
per Laravel 6.4 questo non funziona più ... qualche idea pls?
alex toader,

Userei return redirect()->intended(RouteServiceProvider::HOME);per mantenere il percorso di casa in un posto.
Mateusz,

26

Ho trovato quei due grandi metodi che potrebbero esserti estremamente utili.

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

È possibile applicare questo filtro ai percorsi che richiedono l'autenticazione.

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

Ciò che questo metodo sostanzialmente fa è memorizzare la pagina che stavi cercando di visitare e ti reindirizza alla pagina di accesso .

Quando l'utente è autenticato, puoi chiamare

return Redirect::intended();

e ti reindirizza alla pagina che stavi cercando di raggiungere all'inizio.

È un ottimo modo per farlo anche se di solito utilizzo il metodo seguente.

Redirect::back()

Puoi controllare questo fantastico blog.


Questo è molto meglio delle soluzioni sopra. Le soluzioni di cui sopra richiedono di essere in grado di passare una chiusura alla funzione di accesso che non ho potuto fare con 4.1. Ma questo è stato molto più semplice e ha funzionato così com'è.
user2662680,

20

È possibile utilizzare Redirect :: funzione prevista . Reindirizzerà l'utente all'URL a cui stavano tentando di accedere prima di essere catturati dal filtro Authenticaton. Un URI di fallback può essere fornito a questo metodo nel caso in cui la destinazione prevista non sia disponibile.

In post accedi / registrati:

return Redirect::intended('defaultpageafterlogin');

11

Lo sto usando da un po 'sul mio codice di selezione della lingua. Finché devi solo tornare indietro di solo 1 pagina funziona bene:

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

Non è la soluzione più potente là fuori, ma è super facile e può aiutare a risolvere alcuni enigmi. :)


5
Sì precedente () funziona bene. Ma se il tuo primo tentativo di accesso fallisce (così la pagina 'login fallito' diventa la tua pagina precedente) e il secondo tentativo di accesso ha successo, allora verrai reindirizzato nuovamente alla pagina di accesso (che potrebbe reindirizzarti alla home page).
Shriganesh Shintre,

11

Cambia il costruttore di LoginControllers in:

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

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

Ti reindirizzerà alla pagina PRIMA della pagina di accesso (2 pagine indietro).


L'unico che funziona per me. Deve significare che ho un altro reindirizzamento da qualche parte ma chissà dove.
Arthur Tarasov,

8
return Redirect::intended('/');

questo ti reindirizzerà alla pagina predefinita del tuo progetto, cioè alla pagina iniziale.


6

Per laravel 5. * prova questi.

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

o

return Redirect::intended('/');

5

Laravel 3

Ho modificato leggermente il tuo codice (Vinícius Fragoso Pinheiro) e ho inserito quanto segue in filters.php

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

E poi nel mio 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'));
}

Si noti che i 'redirect'dati della sessione vengono sottoposti a riflash in caso di problemi di autenticazione. Ciò mantiene intatto il reindirizzamento durante eventuali errori di accesso, ma se l'utente fa clic in qualsiasi momento, il successivo processo di accesso non viene interrotto dai dati della sessione.

È inoltre necessario eseguire il reflash dei dati al punto di mostrare il modulo di accesso nel proprio AuthController, altrimenti la catena è rotta:

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


0

Larvel 5.3 ha funzionato per me semplicemente aggiornando LoginController.php

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

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


0

Per Laravel 5.5 e probabilmente 5.4

In App \ Http \ Middleware \ RedirectIfAuthenticated modifica redirect('/home')in redirect()->intended('/home')nella funzione handle:

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

    return $next($request);
}

in App \ Http \ Controllers \ Auth \ LoginController creare la showLoginForm()funzione come segue:

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

In questo modo, se c'era un intento per un'altra pagina, reindirizzerà lì altrimenti reindirizzerà a casa.


0

Sto usando il seguente approccio con un controller di accesso personalizzato e un middleware per Laravel 5.7, ma spero che funzioni in qualsiasi versione di laravel 5

  • all'interno del middleware

    if (Auth::check()){
        return $next($request);
    }
    else{
      return redirect()->guest(route('login'));
    }
  • all'interno del metodo di accesso al controller

    if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('/default');
    }
  • Se devi passare l'URL intenzionale al lato client , puoi provare quanto segue

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

0

Innanzitutto, dovresti sapere come reindirizzare l'utente al percorso 'login':

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

Non così:

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

0

Laravel ora supporta questa funzionalità immediatamente. (Credo dal 5.5 o prima).

Aggiungi un __construct()metodo al tuo Controllercome mostrato di seguito:

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

Dopo il login, i tuoi utenti verranno quindi reindirizzati alla pagina che intendevano visitare inizialmente.

È inoltre possibile aggiungere la funzione di verifica e-mail di Laravel come richiesto dalla logica dell'applicazione:

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

La documentazione contiene un breve esempio:

È anche possibile scegliere a quali metodi del controller si applica il middleware utilizzando except oonly opzioni.

Esempio con except:

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

Esempio con only:

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

Ulteriori informazioni sulle opzioni excepte sul onlymiddleware:


0

se stai usando axios o altra libreria javascript AJAX potresti voler recuperare l'URL e passare al front-end

puoi farlo con il codice qui sotto

   $default = '/';

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

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

Ciò restituirà una stringa formattata json


0

In Laravel 5.8

in App \ Http \ Controllers \ Auth \ LoginController aggiungere il seguente metodo

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

in App \ Http \ Middleware \ RedirectIfAuthenticated sostituisci "return redirect ('/ home');" con il seguente

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

-1

Hai provato questo nel tuo route.php?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','HomeController@index');
});

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

2
Fornisci alcuni commenti da abbinare al tuo codice per fornire un contesto. Grazie
Suever,

-1

Ecco la mia soluzione per 5.1. Avevo bisogno che qualcuno facesse clic sul pulsante "Mi piace" su un post, venissi reindirizzato per accedere, quindi tornare alla pagina originale. Se erano già connessi, ilhref pulsante "Mi piace" veniva intercettato con JavaScript e trasformato in una richiesta AJAX.

Il pulsante è qualcosa di simile <a href="https://stackoverflow.com/like/931">Like This Post!</a>. /like/931è gestito da un LikeController che richiede il authmiddleware.

Nel middleware Authenticate (la handle()funzione), aggiungi qualcosa di simile all'inizio:

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

Passa /auth/logina qualunque sia il tuo URL per l'accesso. Questo codice salva l'URL della pagina originale nella sessione a meno che l'URL non sia l'URL di accesso. Ciò è necessario perché sembra che questo middleware venga chiamato due volte. Non sono sicuro del perché o se sia vero. Ma se non controlli quel condizionale, sarà uguale alla pagina originale corretta, e in qualche modo verrai modificato /auth/login. C'è probabilmente un modo più elegante per farlo.

Quindi, nel LikeControllero qualunque controller che hai che gestisce l'URL del pulsante premuto sulla pagina originale:

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

Questo metodo è super semplice, non richiede l'override di alcuna funzione esistente e funziona alla grande. È possibile che Laravel abbia un modo più semplice per farlo, ma non sono sicuro di cosa si tratti. L'uso della intended()funzione non funziona nel mio caso perché LikeController doveva anche sapere quale fosse l'URL precedente per reindirizzarlo. Essenzialmente due livelli di reindirizzamento all'indietro.


-1

Per Laravel 5.2 (versioni precedenti che non avevo usato)

Incolla il codice nell'app del file \ Http \ Controllers \ Auth \ AurhController.php

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

E importa lo spazio dei nomi: use Session;

Se non hai apportato modifiche al file app \ Http \ Controllers \ Auth \ AurhController.php, puoi semplicemente sostituirlo con il file da GitHub


-1

Laravel 5.2

Se si utilizza un altro middleware come il middleware di amministrazione, è possibile impostare una sessione per url.intended utilizzando quanto segue:

Fondamentalmente dobbiamo impostare manualmente \Session::put('url.intended', \URL::full());per il reindirizzamento.

Esempio

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

Al tentativo di accesso

Assicurati di utilizzare il tentativo di accesso return \Redirect::intended('default_path');


Questo è ciò che redirect()->guest('login')serve.
Emile Bergeron

-1

Per Laravle 5.7, è necessario apportare modifiche in:

Middleware> RedirectIfAuthenticated.php

Cambia questo:

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

        return $next($request);
    }

A questa:

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

        return $next($request);
    }

ritorno reindirizzamento ('/ yourpath');


Che cosa è mypath? (l'utente torna per questo)
Mostafa Norzade,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.