Redirigir a un usuario a la p谩gina que estaba viendo (o a otra, en Laravel)

De pronto un usuario necesita iniciar sesi贸n o registrarse en nuestra aplicaci贸n. 隆Nos interesa que no se pierda de lo que estaba haciendo!

Introducci贸n

Por defecto el middleware auth que Laravel define se encarga de hacer una redirecci贸n, para que el usuario vuelva a la p谩gina a la que estaba tratando de acceder.

Aunque esto funciona correctamente con peticiones GET, no funciona adecuadamente con peticiones POST donde se env铆an ciertos datos.

Es por ello que, hay ocasiones en las que nos conviene anticipar estas situaciones, y ser铆a ideal que Laravel nos entienda si le decimos lo siguiente:

Lleva al usuario al formulario de inicio de sesi贸n. Dile que inicie sesi贸n antes de continuar. Si a煤n no se ha registrado, ofr茅cele un enlace para que lo pueda hacer. Luego tr谩elo de vuelta a esta p谩gina.

Ser铆a genial poder enviar al usuario a un enlace de login (como los 2 siguientes ejemplos) y que sea redirigido a la URL o ruta indicada, incluso si se acaba de registrar:

mi-aplicacion.com/login?redirect_to=/ruta/donde/estaba
mi-aplicacion.com/login?redirect_to=mi-aplicacion.com/ruta/distinta/segun/convenga

Pues eso es justamente lo que vamos a hacer ahora.

Paso 1

Debemos anticiparnos a la situaci贸n y generar el enlace correspondiente para usuarios que a煤n no han iniciado sesi贸n en nuestra aplicaci贸n.

Por ejemplo, supongamos que estoy desarrollando una aplicaci贸n que permite buscar empleo. Esta aplicaci贸n permite a los interesados postular a las ofertas de trabajo.

Postular a un trabajo en mi aplicaci贸n

Me interesa que:

  • Si el usuario ya ha iniciado sesi贸n, entonces se realice una petici贸n POST sobre la ruta que permite postular a trabajos.
  • Si el usuario a煤n no ha iniciado sesi贸n, sea llevado a una p谩gina de login y que pueda registrarse en caso que no lo haya hecho a煤n. Pero que a pesar de todo, vuelva a donde se encontraba antes.

Entonces en mi caso preparar铆a la vista de la siguiente forma:

@if (auth()->check())
    <form action="{{ url('/job/'.$job->id.'/apply') }}" method="post">
        <button type="submit" class="btn blue no-margin">
            Postular al trabajo
        </button>
    </form>
@else
    <a href="{{ url('/login?redirect_to='.url()->current()) }}" class="btn blue no-margin">
        Postular al trabajo
    </a>
@endif

Hasta aqu铆 hay que tener en cuenta lo siguiente:

  • Yo estoy usando url()->current() para obtener la URL actual, de tal forma que el usuario regrese a esta p谩gina luego de autenticarse.
  • Sin embargo, se podr铆a usar una URL (o ruta) totalmente distinta (seg煤n lo necesites).

Paso 2

Si el usuario ya hab铆a iniciado sesi贸n, entonces el formulario realiza una petici贸n POST y no hay nada nuevo.

Pero si no hay ning煤n usuario autenticado, entonces el enlace enviar谩 al usuario a una ruta como la siguiente:

http://tawa.dev.pe:8080/login?redirect_to=http://tawa.dev.pe:8080/empleo/fullstack-developer/2

De seguro ya notaste que:

  • De forma local trabajo con el puerto 8080
  • Tengo un Virtual Host configurado para el host name tawa.dev.pe
  • La URL del empleo al que se intenta postular es http://tawa.dev.pe:8080/empleo/fullstack-developer/2

En fin. Continuemos.

En este segundo paso, debemos preparar a nuestra p谩gina de login para que entienda e interprete el par谩metro redirect_to.

驴C贸mo hacemos eso? 隆Exacto! En LoginController (se encuentra en app/Http/Controllers/Auth).

Si no has hecho ning煤n cambio, el controlador tendr谩 este aspecto:

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/home';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

Respecto al controlador, debes tener en cuenta lo siguiente:

  • El atributo $redirectTo permite definir una ruta, para que todo usuario sea redirigido all铆 luego de iniciar sesi贸n.
  • Esta l贸gica est谩 definida en Laravel, por defecto, si hemos usado php artisan make:auth para generar nuestro sistema de autenticaci贸n.
  • De forma espec铆fica esta l贸gica se encuentra definida dentro del trait AuthenticatesUsers.

Nosotros necesitamos que los usuarios sean redirigidos a una ruta din谩mica, en caso que se haya solicitado una redirecci贸n. Y que se contin煤e usando la ruta constante definida por el atributo $redirectTo de caso contrario.

Para lograr esto vamos a sobreescribir 2 m茅todos.

Por lo tanto a帽adimos los siguientes 2 m茅todos sobre nuestro LoginController:

public function showLoginForm(IlluminateRequest $request)
{
    if ($request->has('redirect_to')) {
        session()->put('redirect_to', $request->input('redirect_to'));
    }

    return view('auth.login');
}

public function redirectTo()
{
    if (session()->has('redirect_to'))
        return session()->pull('redirect_to');

    return $this->redirectTo;
}

Aqu铆:

  • El m茅todo showLoginForm es llamado cuando un usuario visita la p谩gina de inicio de sesi贸n.
  • Entonces creamos una variable de sesi贸n llamada redirect_to en caso que exista un par谩metro con el mismo nombre.
  • El m茅todo redirectTo es llamado cuando llega el momento de redirigir al usuario.
  • Naturalmente s贸lo se redirige a la ruta indicada en el atributo redirectTo. Pero nosotros estamos sobreescribiendo el m茅todo, para que, en caso de existir una variable de sesi贸n, se use el valor de esta variable y de paso deje de existir (ya que eso hace pull, devolver el valor y eliminar la variable de sesi贸n).

Paso 3

Lo que hicimos en el paso 2 sirve para que un usuario sea redirigido a la p谩gina indicada en el par谩metro redirect_to (que es enviado a la ruta /login).

Si queremos que el usuario sea redirigido seg煤n el valor de dicho par谩metro, incluso si se acaba de registrar, debemos tambi茅n aplicar un cambio en RegisterController (para que haga caso a nuestra variable de sesi贸n, la que creamos en LoginController).

Entonces en RegisterController tambi茅n sobreescribimos el m茅todo redirectTo:

public function redirectTo()
{
    if (session()->has('redirect_to'))
        return session()->pull('redirect_to');

    return $this->redirectTo;
}

Recapitulando

Finalmente, vamos a verificar que todo funcione correctamente.

  • Ahora mismo, acabo de dar clic sobre el bot贸n para Postular.
  • Como no hab铆a una sesi贸n activa fui redirigido a http://tawa.dev.pe:8080/login?redirect_to=http://tawa.dev.pe:8080/empleo/fullstack-developer/2.
  • Como "a煤n no me registro", lo voy a hacer ahora dando clic al enlace correspondiente.
Inicio de sesi贸n y registro
  • El enlace de registro me llev贸 a http://tawa.dev.pe:8080/register. Pero, aunque se ha perdido el par谩metro GET de la URL, la variable de sesi贸n sigue existiendo. As铆 que no hay problema.
  • Ingres茅 mis datos. Me registr茅. Y he sido redirigido a la p谩gina donde antes me encontraba. Es decir he vuelto a http://tawa.dev.pe:8080/empleo/fullstack-developer/2.
  • Ahora si presiono el bot贸n Postular podr茅 hacerlo (pero esa es ya, otra historia).

# laravel

Logo de Programaci贸n y m谩s

Ay煤dame a compartir este post si te fue de ayuda.

Y no olvides seguirnos por redes sociales:

Reg铆strate

Inicia sesi贸n para obtener acceso a nuestros cursos y llevar un control de tu progreso.

Cursos recomendados

Curso de Laravel desde Cero

Aprende Laravel

Aprende Laravel desde cero y desarrolla aplicaciones web reales, en tiempo r茅cord, de la mano de Laravel.

Ingresar al curso
Curso de Actualizaci贸n Laravel

Curso de Laravel Upgrade

Actualiza tus proyectos desde cualquier versi贸n hasta la 煤ltima versi贸n estable de Laravel.

Ingresar al curso
Curso de Laravel, Vue.js y Pusher

Aprende Vue.js

Desarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho m谩s.

Ingresar al curso

Antes que te vayas

Inscr铆bete en nuestro curso gratuito de Laravel