Advertisement
  1. Code
  2. PHP

Cómo crear un guardia de autenticación personalizado en Laravel

Scroll to top
Read Time: 19 min

Spanish (Español) translation by CYC (you can also view the original English article)

En este artículo, vamos a cubrir el sistema de autenticación en el Framework de Laravel. El objetivo principal de este artículo es crear una protección de autenticación personalizada extendiendo el sistema de autenticación central.

Laravel proporciona un sistema de autenticación muy sólido en el núcleo que hace que la implementación de la autenticación básica sea muy sencilla. De hecho, solo necesitas ejecutar un par de comandos artisan para configurar el scaffolding de un sistema de autenticación.

Además, el sistema en sí está diseñado de tal manera que podrías ampliarlo y conectar tus adaptadores de autenticación personalizados también. Eso es lo que discutiremos en detalle a lo largo de este artículo. Antes de seguir adelante y profundizar en la implementación de la protección de autenticación personalizada, comenzaremos con una discusión sobre los elementos básicos en el sistema de autenticación de Laravel: guardias y proveedores.

Los elementos principales: guardias y proveedores

El sistema de autenticación de Laravel se compone de dos elementos principales —guardias y proveedores.

Guardias

Podrías pensar en un guardia como una forma de proporcionar la lógica que se utiliza para identificar a los usuarios autenticados. En el núcleo, Laravel proporciona diferentes guardias como sesión y token. El guardia de sesión mantiene el estado del usuario en cada solicitud mediante cookies y, por otro lado, el guardián del token autentica al usuario marcando un token válido en cada solicitud.

Entonces, como puedes ver, el guardia define la lógica de la autenticación, y no es necesario que siempre trate con eso recuperando credenciales válidas desde el back-end. Puedes implementar un guardia que simplemente verifique la presencia de algo específico en los encabezados de solicitud y autentique a los usuarios en función de eso.

Más adelante en este artículo, implementaremos un guardia que verifique ciertos parámetros JSON en los encabezados de solicitud y recupere al usuario válido del back-end de MongoDB.

Proveedores

Si el guardia define la lógica de autenticación, el proveedor de autenticación es responsable de recuperar al usuario del almacenamiento de fondo. Si el guardia requiere que el usuario deba ser validado contra el almacenamiento de back-end, la implementación de recuperación del usuario entra en el proveedor de autenticación.

Laravel se envía con dos proveedores de autenticación predeterminados: base de datos y Eloquent. El proveedor de autenticación de la base de datos se ocupa de la recuperación directa de las credenciales del usuario del almacenamiento de back-end, mientras que Eloquent proporciona una capa de abstracción que hace lo necesario.

En nuestro ejemplo, implementaremos un proveedor de autenticación MongoDB que obtenga las credenciales del usuario desde el back-end de MongoDB.

Entonces esa fue una introducción básica a los guardias y proveedores en el sistema de autenticación de Laravel. A partir de la próxima sección, nos centraremos en el desarrollo del proveedor y protector de autenticación personalizado.

Un vistazo rápido a la configuración del archivo

Echemos un vistazo rápido a la lista de archivos que implementaremos a lo largo de este artículo.

  • config/auth.php: Es el archivo de configuración de autenticación en el que agregaremos una entrada de nuestra guardia personalizada.
  • config/mongo.php: es el archivo que contiene la configuración de MongoDB.
  • app/Services/Contracts/NosqlServiceInterface.php: Es una interfaz que implementa nuestra clase personalizada de base de datos MongoDB.
  • app/Database/MongoDatabase.php: es una clase de base de datos principal que interactúa con MongoDB.
  • app/Models/Auth/User.php: es la clase de modelo de usuario que implementa la declaración Autenticable.
  • app/Extensions/MongoUserProvider.php: es una implementación del proveedor de autenticación.
  • app/Services/Auth/JsonGuard.php: es una implementación del controlador de protección de autenticación.
  • app/Providers/AuthServiceProvider.php: este es un archivo existente que usaremos para agregar nuestros enlaces de contenedor de servicio.
  • app/Http/Controllers/MongoController.php: es un archivo de controlador demo que implementaremos para probar nuestra guardia personalizada.

No te preocupes si la lista de los archivos no tiene mucho sentido aún, ya que discutiremos todo en detalle a medida que avancemos.

Inmersión profunda en la implementación

En esta sección, revisaremos la implementación de los archivos requeridos.

Lo primero que debemos hacer es informar a Laravel sobre nuestra guardia personalizada. Continúa e ingresa los detalles del protector personalizado en el archivo config/auth.php como se muestra.

1
...
2
...
3
'guards' => [
4
    'web' => [
5
        'driver' => 'session',
6
        'provider' => 'users',
7
    ],
8
9
    'api' => [
10
        'driver' => 'token',
11
        'provider' => 'users',
12
    ],
13
    
14
    'custom' => [
15
      'driver' => 'json',
16
      'provider' => 'mongo',
17
    ],
18
],
19
...
20
...

Como puedes ver, hemos agregado nuestro protector personalizado bajo la clave personalizada.

A continuación, debemos agregar una entrada de proveedor asociada en la sección de proveedores.

1
...
2
...
3
'providers' => [
4
    'users' => [
5
        'driver' => 'eloquent',
6
        'model' => App\User::class,
7
    ],
8
    'mongo' => [
9
        'driver' => 'mongo'
10
    ],
11
12
    // 'users' => [

13
    //     'driver' => 'database',

14
    //     'table' => 'users',

15
    // ],

16
],
17
...
18
...

Hemos agregado nuestra entrada de proveedor bajo la clave mongo.

Finalmente, cambiemos el protector de autenticación predeterminado de web a personalizado.

1
...
2
...
3
'defaults' => [
4
    'guard' => 'custom',
5
    'passwords' => 'users',
6
],
7
...
8
...

Por supuesto, no funcionará aún, ya que aún no hemos implementado los archivos necesarios. Y eso es lo que discutiremos en las próximas secciones.

Configura el controlador MongoDB

En esta sección, implementaremos los archivos necesarios que hablan con la instancia de MongoDB subyacente.

Primero crearemos un archivo de configuración config/mongo.php que contenga la configuración de conexión de MongoDB por defecto.

1
<?php
2
return [
3
  'defaults' => [
4
    'host' => '{HOST_IP}',
5
    'port' => '{HOST_PORT}',
6
    'database' => '{DB_NAME}'
7
  ]
8
];

Por supuesto, debes cambiar los valores del marcador de posición según tu configuración.

En lugar de crear directamente una clase que interactúe con MongoDB, crearemos una interfaz en primer lugar.

El beneficio de crear una interfaz es que proporciona una declaración que un desarrollador debe cumplir al implementarlo. Además, nuestra implementación de MongoDB podría intercambiarse fácilmente con otra implementación de NoSQL si fuese necesario.

Continúa y crea una aplicación de archivo de interfaz app/Services/Contracts/NosqlServiceInterface.php con los siguientes contenidos.

1
<?php
2
// app/Services/Contracts/NosqlServiceInterface.php

3
namespace App\Services\Contracts;
4
5
Interface NosqlServiceInterface
6
{
7
  /**

8
   * Create a Document

9
   *

10
   * @param string $collection Collection/Table Name

11
   * @param array  $document   Document

12
   * @return boolean

13
   */
14
  public function create($collection, Array $document);
15
 
16
  /**

17
   * Update a Document

18
   *

19
   * @param string $collection Collection/Table Name

20
   * @param mix    $id         Primary Id

21
   * @param array  $document   Document

22
   * @return boolean

23
   */
24
  public function update($collection, $id, Array $document);
25
26
  /**

27
   * Delete a Document

28
   *

29
   * @param string $collection Collection/Table Name

30
   * @param mix    $id         Primary Id

31
   * @return boolean

32
   */
33
  public function delete($collection, $id);
34
 
35
  /**

36
   * Search Document(s)

37
   *

38
   * @param string $collection Collection/Table Name

39
   * @param array  $criteria   Key-value criteria

40
   * @return array

41
   */
42
  public function find($collection, Array $criteria);
43
}

Es una interfaz bastante simple que declara los métodos CRUD básicos que una clase debe definir y que implementa esta interfaz.

Ahora, definamos una clase real en app/Database/MongoDatabase.php.

1
<?php
2
// app/Database/MongoDatabase.php

3
namespace App\Database;
4
5
use App\Services\Contracts\NosqlServiceInterface;
6
7
class MongoDatabase implements NosqlServiceInterface
8
{
9
  private $connection;
10
  private $database;
11
    
12
  public function __construct($host, $port, $database)
13
  {
14
    $this->connection = new MongoClient( "mongodb://{$host}:{$port}" );
15
    $this->database = $this->connection->{$database};
16
  }
17
 
18
  /**

19
   * @see \App\Services\Contracts\NosqlServiceInterface::find()

20
   */
21
  public function find($collection, Array $criteria)
22
  {
23
    return $this->database->{$collection}->findOne($criteria);
24
  }
25
26
  public function create($collection, Array $document) {}
27
  public function update($collection, $id, Array $document) {}
28
  public function delete($collection, $id) {}
29
}

Por supuesto, supongo que has instalado MongoDB y la extensión de MongoDB PHP correspondiente.

El método __construct instancia la clase MongoClient con los parámetros necesarios. El otro método importante que nos interesa es el método de búsqueda find, el cual recupera el registro según los criterios proporcionados como argumentos de método.

Así que esa fue la implementación del controlador MongoDB, y traté de mantenerlo lo más simple posible.

Configurar el modelo de usuario

Siguiendo los estándares del sistema de autenticación, debemos implementar el modelo de usuario que debe implementar la declaración Illuminate\Contracts\Auth\Authenticatable.

Continúa y crea un archivo en app/Models/Auth/User.php con los siguientes contenidos.

1
<?php
2
// app/Models/Auth/User.php

3
namespace App\Models\Auth;
4
5
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
6
use App\Services\Contracts\NosqlServiceInterface;
7
8
class User implements AuthenticatableContract
9
{
10
  private $conn;
11
 
12
  private $username;
13
  private $password;
14
  protected $rememberTokenName = 'remember_token';
15
16
  public function __construct(NosqlServiceInterface $conn)
17
  {
18
    $this->conn = $conn;
19
  }
20
21
  /**

22
   * Fetch user by Credentials

23
   *

24
   * @param array $credentials

25
   * @return Illuminate\Contracts\Auth\Authenticatable

26
   */
27
  public function fetchUserByCredentials(Array $credentials)
28
  {
29
    $arr_user = $this->conn->find('users', ['username' => $credentials['username']]);
30
    
31
    if (! is_null($arr_user)) {
32
      $this->username = $arr_user['username'];
33
      $this->password = $arr_user['password'];
34
    }
35
36
    return $this;
37
  }
38
39
  /**

40
   * {@inheritDoc}

41
   * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifierName()

42
   */
43
  public function getAuthIdentifierName()
44
  {
45
    return "username";
46
  }
47
 
48
  /**

49
   * {@inheritDoc}

50
   * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifier()

51
   */
52
  public function getAuthIdentifier()
53
  {
54
    return $this->{$this->getAuthIdentifierName()};
55
  }
56
57
  /**

58
   * {@inheritDoc}

59
   * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthPassword()

60
   */
61
  public function getAuthPassword()
62
  {
63
    return $this->password;
64
  }
65
66
  /**

67
   * {@inheritDoc}

68
   * @see \Illuminate\Contracts\Auth\Authenticatable::getRememberToken()

69
   */
70
  public function getRememberToken()
71
  {
72
    if (! empty($this->getRememberTokenName())) {
73
      return $this->{$this->getRememberTokenName()};
74
    }
75
  }
76
77
  /**

78
   * {@inheritDoc}

79
   * @see \Illuminate\Contracts\Auth\Authenticatable::setRememberToken()

80
   */
81
  public function setRememberToken($value)
82
  {
83
    if (! empty($this->getRememberTokenName())) {
84
      $this->{$this->getRememberTokenName()} = $value;
85
    }
86
  }
87
88
  /**

89
   * {@inheritDoc}

90
   * @see \Illuminate\Contracts\Auth\Authenticatable::getRememberTokenName()

91
   */
92
  public function getRememberTokenName()
93
  {
94
    return $this->rememberTokenName;
95
  }
96
}

Ya deberías haber notado que App\Models\Auth\User implementa la declaración Illuminate\Contracts\Auth\Authenticatable.

La mayoría de los métodos implementados en nuestra clase son autoexplicativos. Habiendo dicho eso, hemos definido el método fetchUserByCredentials, el cual recupera al usuario mediante el back end disponible. En nuestro caso, será una clase MongoDatabase a la que se llamará para recuperar la información necesaria.

Así que esa es la implementación del modelo de Usuario.

Configurar el proveedor de autenticación

Como mencionamos anteriormente, el sistema de autenticación de Laravel consta de dos elementos: guardias y proveedores.

En esta sección, crearemos un proveedor de autenticación que se ocupará de la recuperación del usuario desde el back-end.

Continúa y crea un archivo en app/Extensions/MongoUserProvider.php como se muestra a continuación.

1
<?php
2
// app/Extensions/MongoUserProvider.php

3
namespace App\Extensions;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Contracts\Auth\UserProvider;
7
use Illuminate\Contracts\Auth\Authenticatable;
8
9
class MongoUserProvider implements UserProvider
10
{
11
  /**

12
   * The Mongo User Model

13
   */
14
  private $model;
15
16
  /**

17
   * Create a new mongo user provider.

18
   *

19
   * @return \Illuminate\Contracts\Auth\Authenticatable|null

20
   * @return void

21
   */
22
  public function __construct(\App\Models\Auth\User $userModel)
23
  {
24
    $this->model = $userModel;
25
  }
26
27
  /**

28
   * Retrieve a user by the given credentials.

29
   *

30
   * @param  array  $credentials

31
   * @return \Illuminate\Contracts\Auth\Authenticatable|null

32
   */
33
  public function retrieveByCredentials(array $credentials)
34
  {
35
      if (empty($credentials)) {
36
          return;
37
      }
38
39
    $user = $this->model->fetchUserByCredentials(['username' => $credentials['username']]);
40
41
      return $user;
42
  }
43
 
44
  /**

45
   * Validate a user against the given credentials.

46
   *

47
   * @param  \Illuminate\Contracts\Auth\Authenticatable  $user

48
   * @param  array  $credentials  Request credentials

49
   * @return bool

50
   */
51
  public function validateCredentials(Authenticatable $user, Array $credentials)
52
  {
53
      return ($credentials['username'] == $user->getAuthIdentifier() &&
54
    md5($credentials['password']) == $user->getAuthPassword());
55
  }
56
57
  public function retrieveById($identifier) {}
58
59
  public function retrieveByToken($identifier, $token) {}
60
61
  public function updateRememberToken(Authenticatable $user, $token) {}
62
}

De nuevo, debes asegurarte de que el proveedor personalizado debe implementar la declaración Illuminate\Contracts\Auth\UserProvider.

Para seguir avanzando, define dos métodos importantes: retrieveByCredentials y validateCredentials.

El método retrieveByCredentials se usa para recuperar las credenciales de usuario utilizando la clase de modelo del usuario, el cual se discutió en la sección anterior. Por otro lado, el método validateCredentials se usa para validar a un usuario contra un conjunto dado de credenciales.

Y esa fue la implementación de nuestro proveedor de autenticación personalizado. En la siguiente sección, procederemos a crear un guardia que interactúe con el proveedor de autenticación MongoUserProvider.

Configurar la Guardia de autenticación

Como mencionamos anteriormente, el guardia del sistema de autenticación de Laravel indica cómo se autentica al usuario. En nuestro caso, verificaremos la presencia del parámetro de solicitud jsondata que debe contener la cadena de credenciales codificada en JSON.

En esta sección, crearemos un guardia que interactúa con el proveedor de autenticación que se acaba de crear en la última sección.

Ahora vamos a crear un archivo en app/Services/Auth/JsonGuard.php con los siguientes contenidos.

1
<?php
2
// app/Services/Auth/JsonGuard.php

3
namespace App\Services\Auth;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Contracts\Auth\Guard;
7
use Illuminate\Contracts\Auth\UserProvider;
8
use GuzzleHttp\json_decode;
9
use phpDocumentor\Reflection\Types\Array_;
10
use Illuminate\Contracts\Auth\Authenticatable;
11
12
class JsonGuard implements Guard
13
{
14
  protected $request;
15
  protected $provider;
16
  protected $user;
17
18
  /**

19
   * Create a new authentication guard.

20
   *

21
   * @param  \Illuminate\Contracts\Auth\UserProvider  $provider

22
   * @param  \Illuminate\Http\Request  $request

23
   * @return void

24
   */
25
  public function __construct(UserProvider $provider, Request $request)
26
  {
27
    $this->request = $request;
28
    $this->provider = $provider;
29
    $this->user = NULL;
30
  }
31
32
  /**

33
   * Determine if the current user is authenticated.

34
   *

35
   * @return bool

36
   */
37
  public function check()
38
  {
39
    return ! is_null($this->user());
40
  }
41
42
  /**

43
   * Determine if the current user is a guest.

44
   *

45
   * @return bool

46
   */
47
  public function guest()
48
  {
49
    return ! $this->check();
50
  }
51
52
  /**

53
   * Get the currently authenticated user.

54
   *

55
   * @return \Illuminate\Contracts\Auth\Authenticatable|null

56
   */
57
  public function user()
58
  {
59
    if (! is_null($this->user)) {
60
      return $this->user;
61
    }
62
  }
63
    
64
  /**

65
   * Get the JSON params from the current request

66
   *

67
   * @return string

68
   */
69
  public function getJsonParams()
70
  {
71
    $jsondata = $this->request->query('jsondata');
72
73
    return (!empty($jsondata) ? json_decode($jsondata, TRUE) : NULL);
74
  }
75
76
  /**

77
   * Get the ID for the currently authenticated user.

78
   *

79
   * @return string|null

80
  */
81
  public function id()
82
  {
83
    if ($user = $this->user()) {
84
      return $this->user()->getAuthIdentifier();
85
    }
86
  }
87
88
  /**

89
   * Validate a user's credentials.

90
   *

91
   * @return bool

92
   */
93
  public function validate(Array $credentials=[])
94
  {
95
    if (empty($credentials['username']) || empty($credentials['password'])) {
96
      if (!$credentials=$this->getJsonParams()) {
97
        return false;
98
      }
99
    }
100
101
    $user = $this->provider->retrieveByCredentials($credentials);
102
      
103
    if (! is_null($user) && $this->provider->validateCredentials($user, $credentials)) {
104
      $this->setUser($user);
105
106
      return true;
107
    } else {
108
      return false;
109
    }
110
  }
111
112
  /**

113
   * Set the current user.

114
   *

115
   * @param  Array $user User info

116
   * @return void

117
   */
118
  public function setUser(Authenticatable $user)
119
  {
120
    $this->user = $user;
121
    return $this;
122
  }
123
}

En primer lugar, nuestra clase necesita implementar la interfaz Illuminate\Contracts\Auth\Guard. Por lo tanto, necesitamos definir todos los métodos declarados en esa interfaz.

Lo importante a tener en cuenta aquí es que la función __construct requiere una implementación de Illuminate\Contracts\Auth\UserProvider. En nuestro caso, pasaremos una instancia de App\Extensions\MongoUserProvider, como veremos en la sección posterior.

A continuación, hay una función getJsonParams que recupera las credenciales del usuario del parámetro de solicitud llamado jsondata. Como se espera que recibamos una cadena codificada JSON de las credenciales del usuario, hemos utilizado la función json_decode para decodificar los datos JSON.

En la función de validación, lo primero que verificamos es la existencia del argumento $credentials. Si no está presente, llamaremos al método getJsonParams para recuperar las credenciales del usuario de los parámetros de solicitud.

Ahora, vamos a llamar al método retrieveByCredentials del proveedor MongoUserProvider que recupera al usuario de la base de datos de MongoDB. Finalmente, es el método validateCredentials del proveedor MongoUserProvider el que verifica la validez del usuario.

Aquí termina la implementación de nuestra guardia personalizada. La siguiente sección describe cómo unir estas piezas para formar un sistema de autenticación exitoso.

Juntando todo

Hasta ahora, hemos desarrollado todos los elementos del protector de autenticación personalizado. Este debería proporcionarnos un nuevo sistema de autenticación. Sin embargo, no funcionará fuera de la caja ya que en primer lugar, necesitamos registrarlo utilizando los enlaces de contenedor de servicio Laravel.

Como ya debes saber, el proveedor de servicios Laravel es el lugar adecuado para implementar los enlaces necesarios.

Continúa y abre el archivo app/Providers/AuthServiceProvider.php el cual nos permite agregar enlaces de contenedor de servicio de autenticación. Si no contiene ningún cambio personalizado, puedes reemplazarlo con los siguientes contenidos.

1
<?php
2
// app/Providers/AuthServiceProvider.php

3
namespace App\Providers;
4
5
use Illuminate\Support\Facades\Auth;
6
use Illuminate\Support\Facades\Gate;
7
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
8
use App\Services\Auth\JsonGuard;
9
use App\Extensions\MongoUserProvider;
10
use App\Database\MongoDatabase;
11
use App\Models\Auth\User;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Config;
14
15
class AuthServiceProvider extends ServiceProvider
16
{
17
  /**

18
   * The policy mappings for the application.

19
   *

20
   * @var array

21
   */
22
  protected $policies = [
23
    'App\Model' => 'App\Policies\ModelPolicy',
24
  ];
25
26
  /**

27
   * Register any authentication / authorization services.

28
   *

29
   * @return void

30
   */
31
  public function boot()
32
  {
33
    $this->registerPolicies();
34
    
35
    $this->app->bind('App\Database\MongoDatabase', function ($app) {
36
      return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database'));
37
    });
38
    
39
    $this->app->bind('App\Models\Auth\User', function ($app) {
40
      return new User($app->make('App\Database\MongoDatabase'));
41
    });
42
43
    // add custom guard provider

44
    Auth::provider('mongo', function ($app, array $config) {
45
      return new MongoUserProvider($app->make('App\Models\Auth\User'));
46
    });
47
48
    // add custom guard

49
    Auth::extend('json', function ($app, $name, array $config) {
50
      return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
51
    });
52
  }
53
54
  public function register()
55
  {
56
    $this->app->bind(
57
      'App\Services\Contracts\NosqlServiceInterface',
58
      'App\Database\MongoDatabase'
59
    );
60
  }
61
}

Veamos el método de arranque boot que contiene la mayoría de los enlaces de proveedor.

Para empezar, crearemos enlaces para los elementos App\Database\MongoDatabase y App\Models\Auth\User.

1
$this->app->bind('App\Database\MongoDatabase', function ($app) {
2
  return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database'));
3
});
4
5
$this->app->bind('App\Models\Auth\User', function ($app) {
6
  return new User($app->make('App\Database\MongoDatabase'));
7
});

Ha pasado un tiempo en el cual hemos estado hablando de proveedores y guardias, y es hora de conectar nuestro guardia personalizado en el sistema de autenticación Laravel.

Hemos utilizado el método de proveedor de Auth Facade para agregar nuestro proveedor de autenticación personalizado bajo la clave mongo. Recuerda que la clave refleja la configuración que se agregó anteriormente en el archivo auth.php.

1
Auth::provider('mongo', function ($app, array $config) {
2
  return new MongoUserProvider($app->make('App\Models\Auth\User'));
3
});

De manera similar, inyectaremos nuestra implementación de guardia personalizada utilizando el método extendido de la Auth facade.

1
Auth::extend('json', function ($app, $name, array $config) {
2
  return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
3
});

A continuación, hay un método de registro llamado register que hemos utilizado para vincular App\Services\Contracts\NosqlServiceInterface con la implementación de App\Database\MongoDatabase.

1
$this->app->bind(
2
  'App\Services\Contracts\NosqlServiceInterface',
3
  'App\Database\MongoDatabase'
4
);

Por lo tanto, siempre que sea necesario resolver la dependencia App\Services\Contracts\NosqlServiceInterface, Laravel responde con la implementación del adaptador App\Database\MongoDatabase.

El beneficio de usar esta propuesta es que uno puede cambiar fácilmente la implementación dada con una implementación personalizada. Por ejemplo, digamos que a alguien le gustaría reemplazar la implementación App\Database\MongoDatabase con el adaptador CouchDB en el futuro. En ese caso, solo necesitaría agregar el enlace correspondiente en el método de registro.

Por lo tanto, ese era el proveedor de servicios a tu disposición. En este momento, tenemos todo lo que se requiere para probar nuestra implementación de guardia personalizada, por lo que la siguiente y última sección se trata de eso.

¿Funciona?

Has hecho todo el trabajo de configuración de tu primer protector de autenticación personalizado, y ahora es el momento de cosechar los beneficios, ya que vamos a continuar y lo probaremos.

Implementemos rápidamente un controlador bastante básico app/Http/Controllers/MongoController.php como se muestra a continuación.

1
<?php
2
// app/Http/Controllers/MongoController.php

3
namespace App\Http\Controllers;
4
5
use App\Http\Controllers\Controller;
6
use Illuminate\Contracts\Auth\Guard;
7
8
class MongoController extends Controller
9
{
10
  public function login(Guard $auth_guard)
11
  {
12
    if ($auth_guard->validate()) {
13
      // get the current authenticated user

14
      $user = $auth_guard->user();
15
    
16
      echo 'Success!';
17
    } else {
18
      echo 'Not authorized to access this page!';
19
    }
20
  }
21
}

Observa de cerca la dependencia del método de inicio de sesión, que requiere la implementación de la protección Illuminate\Contracts\Auth\Guard. Como hemos configurado el protector personalizado como el protector predeterminado en el archivo auth.php, es App\Services\Auth\JsonGuard que se inyectará en realidad.

A continuación, llamamos al método de validación llamado validate de la clase App\Services\Auth\JsonGuard, que a su vez inicia una serie de llamadas a métodos:

  • Llama al método retrieveByCredentials de la clase App\Extensions\MongoUserProvider.
  • El método retrieveByCredentials llama al método fetchUserByCredentials de la clase User App\Models\Auth\User.
  • El método fetchUserByCredentials llama al método de búsqueda find de App\Database\MongoDatabase para recuperar las credenciales del usuario.
  • Finalmente, el método find de App\Database\MongoDatabase devuelve la respuesta.

Si todo funciona como se espera, deberíamos obtener un usuario autenticado llamando al método user de nuestra guardia.

Para acceder al controlador, debes agregar una ruta asociada en el archivo routes/web.php.

1
Route::get('/custom/mongo/login', 'MongoController@login');

Intenta acceder a la URL http://tu-sitio-laravel/custom/mongo/login sin pasar ningún parámetro y deberías ver un mensaje de "no autorizado".

Por otro lado, prueba algo como http://tu-sitio-laravel/custom/mongo/login?jsondata={"username":"admin","password":"admin"} y eso debería devolver un mensaje de éxito si el usuario está presente en tu base de datos.

Ten en cuenta que esto es solo para fines de ejemplo, para demostrar cómo funciona el protector personalizado. Deberías implementar una solución infalible para una característica como el inicio de sesión. De hecho, acabo de proporcionar una idea del flujo de autenticación; eres responsable de construir una solución robusta y segura para tu aplicación.

Aquí finaliza nuestro viaje de hoy, y con suerte volveré con más cosas útiles. Si quieres que escriba sobre algún tema específico, ¡no olvides dejarme una línea!

Conclusión

El framework de Laravel proporciona un sistema de autenticación sólido en el núcleo que podría ampliarse si deseas implementar uno personalizado. Ese fue el tema del artículo de hoy para implementar un guardia personalizado y conectarlo al flujo de trabajo de autenticación de Laravel.

En el transcurso de eso, continuamos y desarrollamos un sistema que autentica al usuario basado en la carga JSON en la solicitud y lo combina con la base de datos MongoDB. Y para lograr eso, terminamos creando un protector personalizado y una implementación de proveedor personalizado.

Espero que el ejercicio te haya proporcionado una idea del flujo de autenticación de Laravel, y ahora deberías sentirte más seguro acerca de su funcionamiento interno.

Para aquellos de ustedes que recién están comenzando con Laravel o buscando ampliar el conocimiento, sitio o aplicación con extensiones, tenemos una variedad de cosas que pueden estudiar en Envato Market.

Me encantaría escuchar tus comentarios y sugerencias, ¡así que grita en voz alta usando el feed a continuación!.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.