Autenticación

 

# Introducción

Laravel hace que implementar la autenticación sea muy simple. De hecho, casi todo está configurado para usted de inmediato. El archivo de configuración de autenticación se encuentra en config/auth.php, que contiene varias opciones bien documentadas para ajustar el comportamiento de los servicios de autenticación.

En esencia, las instalaciones de autenticación de Laravel están compuestas por "guards" y "providers". Los guards definen cómo se autentican los usuarios para cada solicitud. Por ejemplo, Laravel se envía con un session protector que mantiene el estado mediante el almacenamiento de sesiones y cookies.

Los providers definen cómo se recuperan los usuarios de su almacenamiento persistente. Laravel se envía con soporte para recuperar usuarios usando Eloquent y el generador de consultas de base de datos. Sin embargo, puede definir providers adicionales según sea necesario para su aplicación.

¡No se preocupe si todo esto suena confuso ahora! Muchas aplicaciones nunca necesitarán modificar la configuración de autenticación predeterminada.

 

Comenzando rápido

¿Quieres empezar rápido? Instal Laravel Jetstream en una nueva aplicación Laravel. Después de migrar su base de datos, navegue en su navegador hacia /register o cualquier otra URL asignada a su aplicación. ¡Jetstream se encargará de montar todo su sistema de autenticación!

 

Consideraciones de la base de datos

De forma predeterminada, Laravel incluye un modelo Eloquent App\Models\User en su directorio app/Models.  Este modelo se puede utilizar con el controlador de autenticación predeterminado de Eloquent. Si su aplicación no usa Eloquent, puede usar el controlador de autenticacion de la databaseque usa el generador de consultas de Laravel.

Al crear el esquema de la base de datos para el modelo App\Models\User,asegúrese de que la columna de contraseña tenga al menos 60 caracteres de longitud. Mantener la longitud predeterminada de la columna de cadena de 255 caracteres sería una buena opción.

Además, debe verificar que su tabla users (o equivalente) contenga una columna de cadena remember_token que acepte valores nulos. Esta columna se utilizará para almacenar un token para los usuarios que seleccionen la opción "recordarme" al iniciar sesión en su aplicación.

 

Descripcion general del ecosistema

Laravel ofrece varios paquetes relacionados con la autenticación. Antes de continuar, revisaremos el ecosistema de autenticación general en Laravel y discutiremos el propósito de cada paquete.

Primero, considere cómo funciona la autenticación. Al utilizar un navegador web, el usuario proporcionará su nombre de usuario y contraseña mediante un formulario de inicio de sesión. Si estas credenciales son correctas, la aplicación almacenará información sobre el usuario autenticado en la session del usuario.Una cookie emitida al navegador contiene el ID de sesión para que las solicitudes posteriores a la aplicación puedan asociar al usuario con la sesión correcta. Una vez recibida la cookie de sesión, la aplicación recuperará los datos de la sesión basándose en el ID de la sesión, observará que la información de autenticación se ha almacenado en la sesión y considerará al usuario como "autenticado".

Cuando un servicio remoto necesita autenticarse para acceder a una API, las cookies no se utilizan normalmente porque no hay un navegador web. En cambio, el servicio remoto envía un token de API a la API en cada solicitud. La aplicación puede validar el token entrante contra una tabla de tokens API válidos y "autenticar" la solicitud como realizada por el usuario asociado con ese token API.

 

Servicios de autenticación de navegador integrados de Laravel

Laravel incluye servicios de sesión y autenticación integrados a los que normalmente se accede a través de las fachadas AuthSession. Estas características proporcionan autenticación basada en cookies para solicitudes que se inician desde navegadores web. Proporcionan métodos que le permiten verificar las credenciales de un usuario y autenticar al usuario. Además, estos servicios almacenarán automáticamente los datos adecuados en la sesión del usuario y emitirán la cookie de sesión adecuada. En esta documentación se incluye una explicación de cómo utilizar estos servicios.

Jetstream / Fortify

Como se explica en esta documentación, puede interactuar con estos servicios de autenticación manualmente para crear la capa de autenticación propia de su aplicación. Sin embargo, para ayudarlo a comenzar más rápidamente, hemos lanzado paquetes gratuitos que brindan una estructura sólida y moderna de toda la capa de autenticación. Estos paquetes son Laravel Jetstream and Laravel Fortify.

Laravel Fortify es un backend de autenticación sin cabeza para Laravel que implementa muchas de las características que se encuentran en esta documentación, incluida la autenticación basada en cookies, así como otras características como la autenticación de dos factores y la verificación del correo electrónico. Laravel Jetstream es una interfaz de usuario que consume y expone los servicios de autenticación de Fortify con una hermosa y moderna interfaz de usuario con tecnologías Tailwind CSS, Laravel Livewire, y/o Inertia.js. Laravel Jetstream, además de ofrecer autenticación de cookies basada en navegador, incluye integración incorporada con Laravel Sanctum para ofrecer autenticación de token API. Las ofertas de autenticación de API de Laravel se analizan a continuación.

Servicios de autenticación de API de Laravel

Laravel proporciona dos paquetes opcionales para ayudarlo a administrar tokens API y autenticar solicitudes realizadas con tokens API: PassportSanctum. Tenga en cuenta que estas bibliotecas y las bibliotecas de autenticación basadas en cookies integradas de Laravel no son mutuamente excluyentes. Estas bibliotecas se centran principalmente en la autenticación de token de API, mientras que los servicios de autenticación integrados se centran en la autenticación del navegador basada en cookies. Muchas aplicaciones utilizarán los servicios de autenticación basados ​​en cookies incorporados de Laravel y uno de los paquetes de autenticación API de Laravel.

Passport

Passport es un proveedor de autenticación OAuth2 que ofrece una variedad de "tipos de concesión" de OAuth2 que le permiten emitir varios tipos de tokens. En general, este es un paquete robusto y complejo para la autenticación de API. Sin embargo, la mayoría de las aplicaciones no requieren las funciones complejas que ofrece la especificación OAuth2, lo que puede resultar confuso tanto para los usuarios como para los desarrolladores. Además, los desarrolladores han estado históricamente confundidos acerca de cómo autenticar aplicaciones SPA o aplicaciones móviles utilizando proveedores de autenticación OAuth2 como Passport

Sanctum

En respuesta a la complejidad de OAuth2 y la confusión del desarrollador, nos propusimos crear un paquete de autenticación más simple y optimizado que pudiera manejar tanto las solicitudes web de origen desde un navegador web como las solicitudes de API a través de tokens. Este objetivo se logró con el lanzamiento de Laravel Sanctum, que debe considerarse el paquete de autenticación preferido y recomendado para aplicaciones que ofrecerán una interfaz de usuario web propia además de una API, o que estarán impulsadas por una aplicación de una sola página que existe por separado de la aplicación Laravel backend, o aplicaciones que ofrecen un cliente móvil.

Laravel Sanctum es un paquete de autenticación web / API híbrido que puede administrar todo el proceso de autenticación de su aplicación. Esto es posible porque cuando las aplicaciones basadas en Sanctum reciben una solicitud, Sanctum primero determinará si la solicitud incluye una cookie de sesión que hace referencia a una sesión autenticada. Sanctum logra esto llamando a los servicios de autenticación integrados de Laravel que discutimos anteriormente. Si la solicitud no se está autenticando a través de una cookie de sesión, Sanctum inspeccionará la solicitud de un token de API. Si hay un token de API, Sanctum autenticará la solicitud utilizando ese token. TPara obtener más información sobre este proceso, consulte la documentación de Sanctum "how it works".

Laravel Sanctum es el paquete de API que hemos elegido incluir con el andamio de autenticación de Laravel Jetstream porque creemos que es el que mejor se adapta a la mayoría de las necesidades de autenticación de aplicaciones web.

 

Resumes y elecciones de su pila

En resumen, si se accederá a su aplicación utilizando un navegador, su aplicación utilizará los servicios de autenticación integrados de Laravel.

A continuación, si su aplicación ofrece una API, elegirá entre Passport or Sanctum para proporcionar autenticación de token API para su aplicación. En general, se debe preferir Sanctum cuando sea posible, ya que es una solución simple y completa para la autenticación de API, autenticación de SPA y autenticación móvil, que incluye soporte para "alcances" o "habilidades".

Se puede elegir Passport cuando su aplicación necesita absolutamente todas las características proporcionadas por la especificación OAuth2.

Y, si desea comenzar rápidamente, nos complace recomendar Laravel Jetstream como una forma rápida de iniciar una nueva aplicación Laravel que ya usa nuestra pila de autenticación preferida de los servicios de autenticación integrados de Laravel y Laravel Sanctum.

 

Inicio rápido de autenticación

Esta parte de la documentación analiza la autenticación de usuarios a través del paquete Laravel Jetstream, que incluye andamios de interfaz de usuario para ayudarlo a comenzar rápidamente. Si desea integrarse directamente con los sistemas de autenticación de Laravel, consulte la documentación sobre cómo Autenticar usuarios manualmente.

 

Enrutamiento

En laravel/jetstream paquete de Laravel proporciona una forma rápida de estructurar todas las rutas, vistas y otra lógica de backend necesaria para la autenticación mediante unos pocos comandos simples:

composer require laravel/jetstream

// Install Jetstream with the Livewire stack...
php artisan jetstream:install livewire

// Install Jetstream with the Inertia stack...
php artisan jetstream:install inertia

Este comando debe usarse en aplicaciones nuevas e instalará una vista de diseño, vistas de registro e inicio de sesión, así como rutas para todos los puntos finales de autenticación. En la ruta /dashboard también se generará una ruta para manejar las solicitudes posteriores al inicio de sesión en el panel de su aplicación.

 

Creación de aplicaciónes, incluida la autenticación

Si está iniciando una nueva aplicación y le gustaría incluir el andamio de autenticación, puede usar la directiva --jet al crear su aplicación a través del instalador de Laravel. Este comando creará una nueva aplicación con todos los andamios de autenticación compilados e instalados:

laravel new kitetail --jet

Para obtener más información sobre Jetstream, visite la documentación de Jetstream.

 

Views

Como se mencionó en la sección anterior, el comando laravel/jetstream del paquete php artisan jetstream:install ccreará todas las vistas que necesita para la autenticación y las colocará en el directorio resources/views/auth.

Jetstream también creará un directorio resources/views/layouts que contiene un diseño base para su aplicación. Todas estas vistas utilizan el framework Tailwind CSS, pero puede personalizarlas como desee.

 

Autenticando

Ahora que su aplicación ha sido modificada para la autenticación, ¡está listo para registrarse y autenticarse! Simplemente puede acceder a su aplicación en un navegador, ya que los controladores de autenticación de Jetstream ya contienen la lógica para autenticar a los usuarios existentes y almacenar nuevos usuarios en la base de datos.

 

Personalización de ruta

Cuando un usuario se autentica con éxito, normalmente será redirigido a la URL /home. Puede personalizar la ruta de redireccionamiento posterior a la autenticación utilizando la constante HOME definida en su RouteServiceProvider:

public const HOME = '/home';

Al usar Laravel Jetstream, el proceso de instalación de Jetstream cambiará el valor de la HOME constante a /dashboard.

 

Recuperando el usuario autenticado

Mientras maneja una solicitud entrante, puede acceder al usuario autenticado a través de la facade Auth:

use Illuminate\Support\Facades\Auth;

// Get the currently authenticated user...
$user = Auth::user();

// Get the currently authenticated user's ID...
$id = Auth::id();

Alternativamente, una vez que un usuario está autenticado, puede acceder al usuario autenticado a través de una instancia Illuminate\Http\Request. Recuerde, las clases, type-hinted se inyectarán automáticamente en los métodos de su controlador. Al escribir una sugerencia del objeto Illuminate\Http\Request, puede obtener un acceso conveniente al usuario autenticado desde cualquier método de controlador en su aplicación:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * Get a list of all available flights.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // $request->user() returns an instance of the authenticated user...
    }
}

 

Determinar si el usuario actual esta autenticado

Para determinar si el usuario ya inició sesión en su aplicación, puede usar el metodo check en la facade Auth que regresara true si el usuario está autenticado:

use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // The user is logged in...
}

Aunque es posible determinar si un usuario está autenticado mediante el método check, normalmente utilizará un middleware para verificar que el usuario esté autenticado antes de permitirle el acceso a determinadas rutas / controladores. Para obtener más información sobre esto, consulte la documentación sobre la protecting routes.

 

Protección de rutas

El middleware Route se puede utilizar para permitir que solo los usuarios autenticados accedan a una ruta determinada. Laravel se envía con un middlewate auth, que hace referencia a la clase Illuminate\Auth\Middleware\Authenticate. Dado que este middleware ya está registrado en su kernel HTTP, todo lo que necesita hacer es adjuntar el middleware a una definición de ruta:

Route::get('flights', function () {
    // Only authenticated users may enter...
})->middleware('auth');

 

Redirigir usuarios no autenticados

Cuando el middleware auth  detecta un usuario no autorizado, redirigirá al usuario al login named route. Puede modificar este comportamiento actualizando la función redirectTo en su archivo app/Http/Middleware/Authenticate.php:

/**
 * Get the path the user should be redirected to.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return string
 */
protected function redirectTo($request)
{
    return route('login');
}

 

Especificando un Guard

Al adjuntar el middleware auth en una ruta, también puede especificar qué protección se debe usar para autenticar al usuario. El guard especificado debe corresponder a una de las claves de la matriz guards de su archivo de configuración auth.php:

Route::get('flights', function () {
    // Only authenticated users may enter...
})->middleware('auth:api');

 

Limitación de inicio de sesión

Si está utilizando Laravel Jetstream, la limitación de velocidad se aplicará automáticamente a los intentos de inicio de sesión. De forma predeterminada, el usuario no podrá iniciar sesión durante un minuto si no proporciona las credenciales correctas después de varios intentos. La limitación es única para el nombre de usuario / dirección de correo electrónico del usuario y su dirección IP.

Si desea limitar la tarifa de sus propias rutas, consulte la documentacion de limitación de tarifa.

 

Autenticación manual de usuarios

No es necesario que utilice el andamio de autenticación incluido con Laravel Jetstream. Si elige no usar este andamio, deberá administrar la autenticación de usuario utilizando las clases de autenticación de Laravel directamente. No se preocupe, ¡es pan comido!

Accederemos a los servicios de autenticación de Laravel a través de la facade Auth, por lo que tendremos que asegurarnos de importar el facade Auth en la parte superior de la clase. A continuación, veamos el método attempt:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /**
     * Handle an authentication attempt.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return Response
     */
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            // Authentication passed...
            return redirect()->intended('dashboard');
        }
    }
}

El método attempt acepta una matriz de pares clave / valor como primer argumento. Los valores de la matriz se utilizarán para encontrar al usuario en la tabla de su base de datos. Entonces, en el ejemplo anterior, el usuario será recuperado por el valor de la columna email. Si se encuentra al usuario, la contraseña hash almacenada en la base de datos se comparará con el valor password pasado al método a través del array. o debe aplicar un hash a la contraseña especificada como valor password, ya que el framework automáticamente hará un hash del valor antes de compararlo con la contraseña con hash en la base de datos. Si las dos contraseñas con hash coinciden, se iniciará una sesión autenticada para el usuario.

El método attempt regresará true si la autentificación fue exitosa. De lo contrario será devuelta false.

El método intended en el directorio redirigirá al usuario a la URL a la que intentaba acceder antes de ser interceptado por el middleware de autenticación. Se puede proporcionar un URI alternativo a este método en caso de que el destino previsto no esté disponible.

 

Especificar condiones adicionales

Si lo desea, también puede agregar condiciones adicionales a la consulta de autenticación además del correo electrónico y la contraseña del usuario. Por ejemplo, podemos verificar que el usuario esté marcado como "active":

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}

En estos ejemplos, email no es una opción obligatoria, simplemente se utiliza como ejemplo. Debe utilizar cualquier nombre de columna que corresponda a un "nombre de usuario" en su base de datos.

 

Acceso a instancias de Guard específicas

Puede especificar qué instancia de guard que le gustaría utilizar utilizando el método guard en la facade Auth. Esto le permite administrar la autenticación para partes separadas de su aplicación utilizando modelos o tablas de usuarios autenticables completamente separados.

El nombre de guardia pasado al método guard debe corresponder a uno de los guardias configurados en su archivo de configuración auth.php:

if (Auth::guard('admin')->attempt($credentials)) {
    //
}

 

Saliendo de tu cuenta

Para desconectar a los usuarios de su aplicación, puede utilizar el método logout en la facade Auth. Esto borrará la información de autenticación en la sesión del usuario::

Auth::logout();

 

Recordando a los usuarios

Si desea proporcionar la funcionalidad "recordarme" en su aplicación, puede pasar un valor booleano como segundo argumento del método attempt, lo que mantendrá al usuario autenticado indefinidamente o hasta que cierre la sesión manualmente. Su tabla users debe incluir la columna de tipo string remember_token, que se utilizará para almacenar el token "remember me".

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    // The user is being remembered...
}

Si el usuario esta "recordado", puede utilizar el método viaRemember método para determinar si el usuario fue autenticado mediante la cookie "remember me":

if (Auth::viaRemember()) {
    //
}

 

Otros métodos de autenticación

 

Autenticar una instancia de usuario

Si necesita registrar una instancia de usuario existente en su aplicación, puede llamar al método login con la instancia de usuario. El objeto dado debe ser una implamentación del  contract Illuminate\Contracts\Auth\Authenticatable. El modelo App\Models\User incluido con Laravel ya implementa esta interfaz. Este método de autenticación es útil cuando ya tiene una instancia de usuario válida, como directamente después de que un usuario se registra en su aplicación:

Auth::login($user);

// Login and "remember" the given user...
Auth::login($user, true);

Puede especificar la instancia de guardia que le gustaría usar:

Auth::guard('admin')->login($user);

 

Autentica un usuario por ID

Para iniciar la sesión de un usuario en la aplicación por su ID, puede utilizar el método loginUsingId. Este método acepta la clave principal del usuario que desea autenticar:

Auth::loginUsingId(1);

// Login and "remember" the given user...
Auth::loginUsingId(1, true);

 

Autenticar un usuario una vez

Puede utilizar el método once para iniciar la sesión de un usuario en la aplicación para una sola solicitud. No se utilizarán sesiones ni cookies, lo que significa que este método puede ser útil al crear una API sin estado:

if (Auth::once($credentials)) {
    //
}

 

Autenticación básica HTTP

La autenticación básica HTTP proporciona una forma rápida de autenticar a los usuarios de su aplicación sin configurar una página de "inicio de sesión" dedicada. Para comenzar, adjunte el middleware auth.basic  a su ruta. El middleware auth.basic está incluido con el marco de Laravel, por lo que no es necesario definirlo:

Route::get('profile', function () {
    // Only authenticated users may enter...
})->middleware('auth.basic');

Una vez que el middleware se haya adjuntado a la ruta, se le solicitarán automáticamente las credenciales cuando acceda a la ruta en su navegador. De forma predeterminada, el middleware auth.basic utilizará la columna email del registro de usuario como "nombre de usuario".

 

Una nota sobre FastCGI

Si está utilizando PHP FastCGI, es posible que la autenticación HTTP  básica no funcione correctamente desde el primer momento. Las siguientes líneas deben agregarse a su archivo .htaccess:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

 

Autenticación básica HTTP sin estado

También puede utilizar la autenticación básica HTTP sin configurar una cookie de identificación de usuario en la sesión, lo que es particularmente útil para la autenticación API. Para hacerlo, define a middleware que llame al método onceBasic. Si el método  onceBasic, no devuelve ninguna respuesta , la solicitud puede pasarse a la aplicación:

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\Auth;

class AuthenticateOnceWithBasicAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next)
    {
        return Auth::onceBasic() ?: $next($request);
    }

}

A continuación, register el middleware de ruta y adjuntelo a una ruta:

Route::get('api/user', function () {
    // Only authenticated users may enter...
})->middleware('auth.basic.once');

 

Saliendo de la cuenta

Para desconectar manualmente a los usuarios de su aplicación, puede utilizar el método logout en la facade Auth. Esto borrará la información de autenticación en la sesión del usuario:

use Illuminate\Support\Facades\Auth;

Auth::logout();

 

Invalidación de sesiónes en otros dispositivos

Laravel también proporciona un mecanismo para invalidar y "cerrar sesión" en las sesiones de un usuario que están activas en otros dispositivos sin invalidar la sesión en su dispositivo actual. Esta función se utiliza normalmente cuando un usuario está cambiando o actualizando su contraseña y le gustaría invalidar sesiones en otros dispositivos mientras mantiene autenticado el dispositivo actual.

Antes de comenzar, debe asegurarse de que el middleware Illuminate\Session\Middleware\AuthenticateSession middleware este presente y sin comentarios en el grupo del middleware web de la clase app/Http/Kernel.php :

'web' => [
    // ...
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    // ...
],

Luego, puede usar el método logoutOtherDevices en la facade Auth . Este método requiere que el usuario proporcione su contraseña actual, que su aplicación debe aceptar a través de un formulario de entrada:

use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($password);

Cuando se invoca el método logoutOtherDevices, las otras sesiones del usuario se invalidan por completo, lo que significa que se "cerrarán la sesión" de todos los guardias por los que fueron previamente autenticados

Cuando utilice el middleware AuthenticateSession en combinación con un nombre de ruta personalizado para la ruta login, debe anular el método unauthenticated en el controlador de excepciones de su aplicación para redirigir correctamente a los usuarios a su página de inicio de sesión.

 

Confirmación de contraseñas

Mientras crea su aplicación, es posible que ocasionalmente tenga acciones que requieran que el usuario confirme su contraseña antes de realizar la acción. Laravel incluye middleware integrado para facilitar este proceso. La implementación de esta función requerirá que defina dos rutas: una ruta para mostrar una vista que le pide al usuario que confirme su contraseña y una ruta para confirmar que la contraseña es válida y redirigir al usuario a su destino previsto.

La siguiente documentación analiza cómo integrarse directamente con las funciones de confirmación de contraseña de Laravel; sin embargo, si desea comenzar más rápidamente, el paquete de andamios de autenticación de Laravel Jetstream incluye soporte para esta función.

 

Configuración

Después de confirmar su contraseña, no se le pedirá al usuario que vuelva a confirmar su contraseña durante tres horas. Sin embargo, puede configurar el período de tiempo antes de que se le vuelva a solicitar la contraseña al usuario cambiando el valo de configuración password_timeout dentro de archivo de configuración auth.

 

Enrutamiento

 

El formulario de confirmación de contraseña

Primero, definiremos la ruta que se necesita para mostrar una vista solicitando al usuario que confirme su contraseña:

Route::get('/confirm-password', function () {
    return view('auth.confirm-password');
})->middleware(['auth'])->name('password.confirm');

Como era de esperar, la vista que devuelve esta ruta debe tener un formulario que contenga un campo password. Además, siéntase libre de incluir texto dentro de la vista que explique que el usuario está ingresando a un área protegida de la aplicación y debe confirmar su contraseña.

 

Confirmación de la contraseña

A continuación, definiremos una ruta que manejará la solicitud de formulario desde la vista "confirmar contraseña". Esta ruta será responsable de validar la contraseña y redirigir al usuario a su destino previsto:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

Route::post('/confirm-password', function (Request $request) {
    if (! Hash::check($request->password, $request->user()->password)) {
        return back()->withErrors([
            'password' => ['The provided password does not match our records.']
        ]);
    }

    $request->session()->passwordConfirmed();

    return redirect()->intended();
})->middleware(['auth', 'throttle:6,1'])->name('password.confirm');

Antes de continuar, examinemos esta ruta con más detalle. Primero, de determina que el atributo password de la solicitud, coincida realmente con la contraseña del usuario autenticado. Si la contraseña es válida, debemos informar a la sesión de Laravel que el usuario ha confirmado su contraseña. El método passwordConfirmed establecerá una marca de tiempo en la sesión del usuario que Laravel puede usar para determinar cuándo el usuario confirmó por última vez su contraseña. Finalmente, podemos redirigir al usuario a su destino previsto.

 

Protección de rutas

Debe asegurarse de que se asigne el middleware password.confirm a cualquier ruta que realice una acción que deba requerir una confirmación de contraseña reciente. Este middleware se incluye con la instalación predeterminada de Laravel y almacenará automáticamente el destino deseado del usuario en la sesión para que el usuario pueda ser redirigido a esa ubicación después de confirmar su contraseña. Después de almacenar el destino previsto del usuario en la sesión, el middleware redirigirá al usuario a la ruta con nombre  password.confirm :

Route::get('/settings', function () {
    // ...
})->middleware(['password.confirm']);

Route::post('/settings', function () {
    // ...
})->middleware(['password.confirm']);

 

Agregar Guards personalizados

Puede definir sus propias protecciones de autenticación utilizando el método extend de la facade Auth. Debe realizar esta llamada para extender dentro de un service provider. Dado que Laravel ya se envía con un AuthServiceProvider, podemos colocar el código en ese proveedor:

<?php

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::extend('jwt', function ($app, $name, array $config) {
            // Return an instance of Illuminate\Contracts\Auth\Guard...

            return new JwtGuard(Auth::createUserProvider($config['provider']));
        });
    }
}

Como puede ver en el ejemplo anterior, la devolución de llamada pasada al método extend debería devolver una implementación de Illuminate\Contracts\Auth\Guard.  Esta interfaz contiene algunos métodos que deberá implementar para definir una protección personalizada. Una vez que se ha definido su protección personalizada, puede utilizar esta protección en la guards configuración de su archivo de configuración auth.php:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

 

Guards de solicitud de cierre

La forma más sencilla de implementar un sistema de autenticación personalizado basado en solicitudes HTTP es mediante el método Auth::viaRequest. Este método le permite definir rápidamente su proceso de autenticación utilizando un solo cierre.

Para comenzar, llame al método Auth::viaRequest dentro del método boot de su AuthServiceProvider. El método viaRequest acepta un nombre de controlador de autenticación como primer argumento. Este nombre puede ser cualquier cadena que describa su guardia personalizada. El segundo argumento pasado al método debería ser un cierre que recibe la solicitud HTTP entrante y devuelve una instancia de usuario o, si falla la autenticación, null:

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

/**
 * Register any application authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Auth::viaRequest('custom-token', function ($request) {
        return User::where('token', $request->token)->first();
    });
}

Una vez que se ha definido su controlador de autenticación personalizado, lo usa como un controlador dentro de la configuración de guards de su archivo de configuración auth.php:

'guards' => [
    'api' => [
        'driver' => 'custom-token',
    ],
],

 

Agregar proveedores de usuarios personalizados

Si no está utilizando una base de datos relacional tradicional para almacenar sus usuarios, deberá ampliar Laravel con su propio proveedor de usuarios de autenticación. Usaremos el método provider en la facade Auth para definir un proveedor de usuario personalizado:

<?php

namespace App\Providers;

use App\Extensions\RiakUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::provider('riak', function ($app, array $config) {
            // Return an instance of Illuminate\Contracts\Auth\UserProvider...

            return new RiakUserProvider($app->make('riak.connection'));
        });
    }
}

Una vez que haya registrado el proveedor utilizando el método provider,  puede cambiar al nuevo proveedor de usuario en su archivo de configuración auth.php. Primero, defina un provider que use su nuevo controllador

'providers' => [
    'users' => [
        'driver' => 'riak',
    ],
],

Finalmente, puede usar este proveedor en su configuración de guards:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
],

 

El contrato de proveedor de usuario

Las implementaciones Illuminate\Contracts\Auth\UserProvider solo son responsables de obtener una implementación Illuminate\Contracts\Auth\Authenticatable de un sistema de almacenamiento persistente, como MySQL, Riak, etc. Estas dos interfaces permiten que los mecanismos de autenticación de Laravel sigan funcionando independientemente de cómo se almacenan los datos del usuario o qué tipo de clase se utiliza para representarlo.

Echemos un vistazo al contrato Illuminate\Contracts\Auth\UserProvider:

<?php

namespace Illuminate\Contracts\Auth;

interface UserProvider
{
    public function retrieveById($identifier);
    public function retrieveByToken($identifier, $token);
    public function updateRememberToken(Authenticatable $user, $token);
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(Authenticatable $user, array $credentials);
}

La función retrieveById normalmente recibe una clave que representa al usuario, como un ID de incremento automático de una base de datos MySQL. El método Authenticatable debe recuperar y devolver la implementación que coincida con el ID.

La función retrieveByToken recupera un usuario por su unico $identifier y $token "remember me" , stored in a field remember_token. Al igual que con el metodo anterior de debe devolver la implentación Authenticatable.

El método updateRememberToken actualiza el campo $user con el nuevo $token remember_token. Se asigna un token nuevo en un intento de inicio de sesión "recuérdame" exitoso o cuando el usuario cierra la sesión.

El método retrieveByCredentials ecibe la matriz de credenciales pasadas al método Auth::attempt cuando intenta iniciar sesión en una aplicación. Luego, el método debe "consultar" el almacenamiento persistente subyacente para el usuario que coincida con esas credenciales. Normalmente, este método ejecutará una consulta con una condición "where" $credentials['username']. Entonces, el método debería devolver una implementación de Authenticatable. Este método no debe intentar realizar ninguna validación o autenticación de contraseña.

El método validateCredentials debe comparar el $user dado con las $credentials para autenticar al usuario. Por ejemplo, este método probablemente debería usarse Hash::check para comparar el valor de $user->getAuthPassword() con el valor de $credentials['password']. Este método debe devolver true o false indicating on whether the password is valid.

 

El contrato autenticable

Ahora que hemos explorado cada uno de los métodos en el UserProvider, echemos un vistazo al contrato Authenticatable. Recuerde, el proveedor debe devolver las implementaciones de esta interfaz desde los métodos retrieveById, retrieveByToken, y retrieveByCredentials:

<?php

namespace Illuminate\Contracts\Auth;

interface Authenticatable
{
    public function getAuthIdentifierName();
    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();
}

Esta interfaz es simple. El método getAuthIdentifierName debe devolver el nombre del campo "primary key"  del usuario y el método getAuthIdentifier deve devolcer "primary key" del usuario.  En un back-end de MySQL, nuevamente, esta sería la clave primaria de incremento automático. El getAuthPassword debe devolver la contraseña hash del usuario. Esta interfaz permite que el sistema de autenticación funcione con cualquier clase de usuario, independientemente del ORM o la capa de abstracción de almacenamiento que esté utilizando. De forma predeterminada, Laravel incluye unas clase User en el directorio app/Models que implementa esta interfaz, por lo que puede consultar esta clase para obtener un ejemplo de implementación.

 

Events

Laravel genera una variedad de events durante el proceso de autenticación. Puede adjuntar oyentes a estos eventos en su EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Auth\Events\Registered' => [
        'App\Listeners\LogRegisteredUser',
    ],

    'Illuminate\Auth\Events\Attempting' => [
        'App\Listeners\LogAuthenticationAttempt',
    ],

    'Illuminate\Auth\Events\Authenticated' => [
        'App\Listeners\LogAuthenticated',
    ],

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],

    'Illuminate\Auth\Events\Failed' => [
        'App\Listeners\LogFailedLogin',
    ],

    'Illuminate\Auth\Events\Validated' => [
        'App\Listeners\LogValidated',
    ],

    'Illuminate\Auth\Events\Verified' => [
        'App\Listeners\LogVerified',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],

    'Illuminate\Auth\Events\CurrentDeviceLogout' => [
        'App\Listeners\LogCurrentDeviceLogout',
    ],

    'Illuminate\Auth\Events\OtherDeviceLogout' => [
        'App\Listeners\LogOtherDeviceLogout',
    ],

    'Illuminate\Auth\Events\Lockout' => [
        'App\Listeners\LogLockout',
    ],

    'Illuminate\Auth\Events\PasswordReset' => [
        'App\Listeners\LogPasswordReset',
    ],
];