Actualizado el miércoles, 1 mayo, 2024

Laravel Auth cuenta con una función para redirigir al usuario conectado a la misma página que estaba visitando antes. Así, por ejemplo, si visitas /posts, eres redirigido automáticamente a /login y luego introduces tus datos con éxito, Laravel lo «recordará» y te redirigirá de nuevo a /posts en lugar de a /home por defecto. Pero no funciona con el registro de nuevos usuarios, veamos cómo podemos cambiarlo.

Imagina el escenario:

Usted visita la URL de /posts;
El sistema utiliza el middleware ‘auth’ y te redirige de vuelta a /login;
Pero aún no tienes un usuario, así que haces clic en Register y llegas a la URL /register;
Y entonces, después de registrarse con éxito, ¿a dónde se le redirige? A la URL por defecto /home, o lo que se especifique en la propiedad $redirectTo en RegisterController.
Entonces, ¿cómo personalizarlo y hacer que Laravel «recuerde» la página anterior para el registro, también? Vamos a profundizar en cómo funciona internamente el Auth.

De hecho, ya almacena esa información, sólo tenemos que utilizarla.

Si profundizamos en la lógica de LoginController, utiliza el Trait AuthenticatesUsers.php de la carpeta /vendor del núcleo de Laravel. Y tiene este método:

public function login(Request $request)
{
    // ...

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    // ...

}

Profundicemos: ¿qué es sendLoginResponse()? Dentro del mismo Trait:

protected function sendLoginResponse(Request $request)
{
    // ...

    return $this->authenticated($request, $this->guard()->user())
            ?: redirect()->intended($this->redirectPath());
}

Como puede ver, utiliza el método redirect()->intended(). ¿Cómo funciona? La documentación oficial de Laravel lo describe así

El método intended en el redirector redirigirá al usuario a la URL a la que estaba intentando acceder antes de ser interceptado por el middleware de autenticación.

Bajo el capó, su lógica está en /vendor/laravel/framework/src/Illuminate/Routing/Redirector.php:

public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
    $path = $this->session->pull('url.intended', $default);

    return $this->to($path, $status, $headers, $secure);
}

Ahora, echemos un vistazo a app/Http/Controllers/Auth/RegisterController.php, también utiliza un Trait del núcleo:

trait RegistersUsers
{
    use RedirectsUsers;

    // ...

    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
                        ?: redirect($this->redirectPath());
    }

Fíjate en la última parte de la redirección. Como puedes ver, utiliza redirect() simple, sin intended(). Así que esta es la parte que tenemos que cambiar.

Pero no podemos editar eso directamente en la carpeta /vendor, lo que hacemos es copiar-pegar el mismo método del Trait en RegisterController, y cambiar la parte de redirección:

class RegisterController extends Controller
{

    use RegistersUsers;

    // ...

    /**
     * Handle a registration request for the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
            ?: redirect()->intended($this->redirectPath());
    }

}

Y, eso es todo – ahora, después del registro el usuario será redirigido a la página que estaba visitando antes de que el middleware ‘auth’ restringiera su acceso.