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.
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.
@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 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
.
$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 hacepull
, 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ámetroredirect_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.
- 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).
0 Comentarios