web-dev-qa-db-fra.com

Laravel redirige vers la destination d'origine après la connexion

Cela semble être un flux assez basique, et Laravel a tellement de solutions intéressantes pour les choses basiques, je sens que je manque quelque chose.

Un utilisateur clique sur un lien nécessitant une authentification. Le filtre auth de Laravel entre en action et les achemine vers une page de connexion. L'utilisateur se connecte, puis retourne à la page d'origine à laquelle il tentait d'accéder avant le démarrage du filtre "auth".

Existe-t-il un bon moyen de savoir à quelle page ils essayaient d'accéder à l'origine? Comme Laravel est celui qui intercepte la demande, je ne savais pas s'il gardait une trace quelque part pour faciliter le routage après la connexion de l'utilisateur.

Sinon, je serais curieux de savoir comment certains d'entre vous ont implémenté cela manuellement.

157
JOV

Pour Laravel 5.3 et supérieur

Vérifiez la réponse de Scott ci-dessous.

Pour Laravel 5 jusqu'à 5.2

Tout simplement,

Sur le middleware d'authentification:

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

Sur l'action de connexion:

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

Pour Laravel 4 (ancienne réponse)

Au moment de cette réponse, il n'y avait aucun soutien officiel du cadre lui-même. De nos jours, vous pouvez utiliser la méthode indiquée par bgdrl ci-dessous cette méthode: (j'ai essayé de mettre à jour sa réponse, mais il semble qu'il ne l'acceptera pas)

Sur le filtre d'authentification:

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

Sur l'action de connexion:

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

Pour Laravel 3 (réponse encore plus ancienne)

Vous pouvez l'implémenter comme ceci:

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

Le stockage de la redirection sur une session présente l’avantage de la conserver même si l’utilisateur manque ses informations d’identification ou s’il n’a pas de compte et doit s’inscrire.

Cela permet également à tout le monde, à part Auth, de définir une redirection sur la session et que cela fonctionnera comme par magie.

215
vFragosop

Laravel> = 5.3

Les modifications apportées à Auth dans la version 5.3 rendent la mise en œuvre un peu plus facile et légèrement différente de la version 5.2, car Auth Middleware a été déplacé vers le conteneur de services.

Modifier le nouveau redirecteur d'authentification de middleware

/app/Http/Middleware/RedirectIfAuthenticated.php

Modifiez légèrement la fonction de la poignée, ainsi:

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

    return $next($request);
}

Explication TL; DR

La seule différence est dans la 4ème ligne; par défaut cela ressemble à ceci:

return redirect("/home");

Dans la mesure où Laravel> = 5.3 enregistre automatiquement le dernier itinéraire "prévu" lors de la vérification de l'Authentic Guard, il est remplacé par:

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

Cela demande à Laravel de rediriger vers la dernière page prévue avant la connexion, sinon, allez à "/ home" ou à l'endroit où vous souhaitez les envoyer par défaut.

J'espère que cela aidera quelqu'un d'autre - les différences entre 5.2 et 5.3 sont peu nombreuses et, dans ce domaine en particulier, il y en a pas mal.

52
Scott Byers

J'ai trouvé ces deux méthodes intéressantes qui pourraient vous être extrêmement utiles.

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

Vous pouvez appliquer ce filtre aux itinéraires nécessitant une authentification.

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

Cette méthode consiste essentiellement à stocker la page que vous tentiez de consulter et à vous rediriger vers la page login.

Lorsque l'utilisateur est authentifié, vous pouvez appeler

return Redirect::intended();

et cela vous redirige vers la page que vous vouliez atteindre au début.

C'est un excellent moyen de le faire bien que j'utilise habituellement la méthode ci-dessous.

Redirect::back()

Vous pouvez vérifier ceci blog génial.

25

Vous pouvez utiliser Redirect :: intentionnel fonction. Il redirigera l'utilisateur vers l'URL auquel il tentait d'accéder avant d'être attrapé par le filtre d'authentification. Une adresse URI de secours peut être donnée à cette méthode Au cas où la destination prévue ne serait pas disponible.

En post login/register:

return Redirect::intended('defaultpageafterlogin');
20
dabuno

Je l’utilise depuis un moment sur mon code de sélecteur de langue. Tant que vous n’avez besoin que de revenir en arrière d’une seule page, cela fonctionne bien:

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

Ce n’est pas la solution la plus puissante, mais c’est très simple et peut aider à résoudre quelques énigmes. :)

11
Federico Stango
return Redirect::intended('/');

cela vous redirigera vers la page par défaut de votre projet, c'est-à-dire la page de démarrage.

8
Parag Bhingre

Changez votre constructeur LoginControllers en:

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

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

Il vous redirigera vers la page AVANT la page de connexion (2 pages en arrière).

7
MevlütÖzdemir

Pour Laravel 5. * essayez-les.

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

ou 

return Redirect::intended('/');
6
Nuruzzaman Milon

Laravel 3

J'ai légèrement modifié votre code (Vinícius Fragoso Pinheiro) et placé les éléments suivants dans 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');
    }
});

Et puis dans le mon 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'));
}

Notez que les données de session 'redirect' sont remises à zéro en cas de problème d'authentification. Ceci maintient la redirection intacte lors de tout incident de connexion, mais si l'utilisateur clique à tout moment, le processus de connexion suivant n'est pas interrompu par les données de la session.

Vous devez également reflasher les données au moment de montrer le formulaire de connexion dans votre AuthController, sinon la chaîne est cassée:

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

Utilisez Redirect;

Alors utilisez ceci:

return Redirect::back();
3
ujwal dhakal

Pour Laravel 5.5 et probablement 5.4

Dans App\Http\Middleware\RedirectIfAuthenticated changez redirect('/home') en redirect()->intended('/home') dans la fonction handle:

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

    return $next($request);
}

dans App\Http\Controllers\Auth\LoginController créez la fonction showLoginForm() comme suit:

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

De cette façon, s'il y avait une intention pour une autre page, elle y sera redirigée, sinon elle sera redirigée vers la maison.

0
DerDare

Pour Laravle 5.7, vous devez effectuer les modifications suivantes: 

Middleware> RedirectIfAuthenticated.php

Change ça:

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

        return $next($request);
    }

Pour ça:

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

        return $next($request);
    }

retourne la redirection ('/ yourpath');

0
Prince Ahmed

Laravel supporte maintenant cette fonctionnalité prête à l'emploi! (je crois depuis la version 5.5 ou antérieure).

Ajoutez une méthode __construct() à votre Controller comme indiqué ci-dessous:

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

Après la connexion, vos utilisateurs seront redirigés vers la page qu’ils avaient l’intention de visiter initialement.

Vous pouvez également ajouter la fonctionnalité de vérification du courrier électronique de Laravel comme requis par votre logique d'application:

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

La documentation contient un exemple très bref:

Bonus: Il est également possible de choisir les méthodes du contrôleur auxquelles le middleware s'applique en utilisant les options except ou only.

Exemple avec except:

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

Exemple avec only:

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

Plus d'informations sur les options de middleware except et only:

0
LobsterBaz

J'utilise l'approche suivante avec un contrôleur de connexion personnalisé et un middleware pour Laravel 5.7, mais j'espère que cela fonctionne dans toutes les versions de Laravel 5

  • middleware intérieur

    if (Auth::check()){
        return $next($request);
    }
    else{
      return redirect()->guest(route('login'));
    }
    
  • méthode de connexion interne du contrôleur

    if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('/default');
    }
    
  • Si vous devez transmettre l’URL prévue à côté client , vous pouvez essayer les solutions suivantes 

       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
Nayeem Azad