Advertisement
  1. Code
  2. PHP
  3. Laravel

Comment créer une garde d'authentification personnalisée dans Laravel

Scroll to top
Read Time: 19 min

() translation by (you can also view the original English article)

Dans cet article, nous allons couvrir le système d’authentification dans le framework Laravel. L'objectif principal de cet article est de créer une protection d'authentification personnalisée en étendant le système d'authentification principal.

Laravel fournit un système d'authentification très solide dans le noyau qui facilite grandement la mise en œuvre de l'authentification de base. En fait, il vous suffit d'exécuter quelques commandes artisanales pour configurer l'échafaudage d'un système d'authentification.

De plus, le système lui-même est conçu de manière à pouvoir être étendu et connecté à vos adaptateurs d’authentification personnalisés. C’est ce dont nous discuterons en détail tout au long de cet article. Avant de nous lancer dans l’implémentation de la protection d’authentification personnalisée, nous commencerons par une discussion des éléments de base du système d’authentification Laravel, à savoir les gardes et les fournisseurs.

Les éléments fondamentaux: gardes et fournisseurs

Le système d'authentification Laravel est composé de deux éléments principaux: les gardes et les fournisseurs.

Gardes

Vous pourriez penser à une protection comme un moyen de fournir la logique utilisée pour identifier les utilisateurs authentifiés. Dans le noyau, Laravel fournit différents gardes comme session et jeton. Le gardien de session maintient l'état de l'utilisateur dans chaque demande par le biais de cookies. D'autre part, le gardien de jeton authentifie l'utilisateur en vérifiant un jeton valide dans chaque demande.

Ainsi, comme vous pouvez le constater, le service de garde définit la logique de l’authentification et il n’est pas nécessaire qu’il traite toujours de cette information en récupérant des informations d’identification valides du serveur principal. Vous pouvez implémenter une protection qui vérifie simplement la présence d'une chose spécifique dans les en-têtes de demande et authentifie les utilisateurs en fonction de cela.

Plus loin dans cet article, nous allons implémenter une protection qui vérifie certains paramètres JSON dans les en-têtes de requête et récupère l'utilisateur valide à partir du back-end de MongoDB.

Fournisseurs

Si la protection définit la logique d'authentification, le fournisseur d'authentification est chargé de récupérer l'utilisateur à partir du stockage principal. Si la protection exige que l'utilisateur soit validé par rapport au stockage principal, la mise en œuvre de la récupération de l'utilisateur passe par le fournisseur d'authentification.

Laravel est livré avec deux fournisseurs d'authentification par défaut, Base de données et Eloquent. Le fournisseur d'authentification de base de données traite de l'extraction directe des informations d'identification de l'utilisateur depuis le stockage principal, tandis qu'Eloquent fournit une couche d'abstraction qui répond aux besoins.

Dans notre exemple, nous allons implémenter un fournisseur d'authentification MongoDB qui récupère les informations d'identification de l'utilisateur à partir du backend MongoDB.

C'était donc une introduction de base aux gardes et aux fournisseurs dans le système d'authentification Laravel. À partir de la section suivante, nous nous concentrerons sur le développement de la protection et du fournisseur d’authentification personnalisés!

Un coup d'œil sur la configuration du fichier

Examinons rapidement la liste des fichiers que nous allons implémenter tout au long de cet article.

  • config/auth.php: C'est le fichier de configuration de l'authentification dans lequel nous ajouterons une entrée de notre garde personnalisée
  • config / mongo.php: C'est le fichier qui contient la configuration de MongoDB.
  • app/Services/Contracts/NosqlServiceInterface.php: Il s'agit d'une interface implémentée par notre classe de base de données Mongo personnalisée.
  • app/Database/MongoDatabase.php: Il s'agit d'une classe de base de données principale qui interagit avec MongoDB.
  • app/Models/Auth/User.php: Il s'agit de la classe de modèle User qui implémente le contrat Authenticable.
  • app/Extensions/MongoUserProvider.php: Il s'agit d'une implémentation du fournisseur d'authentification.
  • app/Services/Auth/JsonGuard.php: C'est une implémentation du pilote de protection d'authentification.
  • app/Providers/AuthServiceProvider.php: Il s'agit d'un fichier existant que nous utiliserons pour ajouter nos liaisons de conteneur de service.
  • app/Http/Controllers/MongoController.php: C'est un fichier de contrôleur de démonstration que nous allons implémenter pour tester notre garde personnalisée.

Ne vous inquiétez pas si la liste des fichiers n'a pas encore beaucoup de sens, car nous allons en discuter en détail.

Plongez dans l'implémentation

Dans cette section, nous allons passer en revue la mise en œuvre des fichiers requis.

La première chose à faire est d'informer Laravel de notre garde sur mesure. Allez-y et entrez les détails de la garde personnalisée dans le fichier config/auth.php comme indiqué.

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
...

Comme vous pouvez le constater, nous avons ajouté notre garde personnalisée sous la clé personnalisée.

Ensuite, nous devons ajouter une entrée de fournisseur associé dans la section des fournisseurs.

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
...

Nous avons ajouté l'entrée de notre fournisseur sous la clé Mongo.

Enfin, modifions la protection d'authentification par défaut de Web à personnalisée.

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

Bien sûr, cela ne fonctionnera pas encore car nous n’avons pas encore implémenté les fichiers nécessaires. Et c'est ce que nous discuterons dans les deux prochaines sections.

Configurer le pilote MongoDB

Dans cette section, nous allons implémenter les fichiers nécessaires qui parlent à l’instance MongoDB sous-jacente.

Commençons par créer un fichier de configuration config/mongo.php contenant les paramètres de connexion par défaut de MongoDB.

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

Bien sûr, vous devez modifier les valeurs d’espace réservé conformément à vos paramètres.

Au lieu de créer directement une classe qui interagit avec MongoDB, nous allons créer une interface en premier lieu.

L'avantage de créer une interface est qu'elle fournit un contrat qu'un développeur doit respecter lors de sa mise en œuvre. De plus, notre implémentation de MongoDB pourrait être facilement remplacée par une autre implémentation NoSQL si nécessaire.

Créez ensuite un fichier d'interface app/Services/Contracts/NosqlServiceInterface.php avec le contenu suivant.

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
}

C'est une interface assez simple qui déclare les méthodes de base CRUD qu'une classe doit définir pour implémenter cette interface.

Maintenant, définissons une classe réelle à 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
}

Bien entendu, je suppose que vous avez installé MongoDB et l’extension PHP MongoDB correspondante.

La méthode __construct instancie la classe MongoClient avec les paramètres nécessaires. L'autre méthode importante qui nous intéresse est la méthode find, qui récupère l'enregistrement en fonction des critères fournis en tant qu'arguments de la méthode.

C’était donc l’implémentation du pilote MongoDB et j’ai essayé de le garder le plus simple possible.

Configurer le modèle utilisateur

Conformément aux normes du système d'authentification, nous devons implémenter le modèle utilisateur qui doit implémenter le contrat Illuminate\Contracts\Auth\Authenticatable.

Allez-y et créez un fichier app/Models/Auth/User.php avec le contenu suivant.

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
}

Vous devriez déjà avoir remarqué que App\Models\Auth\User implémente le contrat Illuminate\Contracts\Auth\Authenticatable.

La plupart des méthodes mises en œuvre dans notre classe s'expliquent d'elles-mêmes. Cela dit, nous avons défini la méthode fetchUserByCredentials, qui extrait l'utilisateur du back-end disponible. Dans notre cas, ce sera une classe MongoDatabase qui sera appelée pour récupérer les informations nécessaires.

Voilà donc la mise en œuvre du modèle utilisateur.

Configurer le fournisseur d'authentification

Comme nous l'avons vu précédemment, le système d'authentification Laravel est constitué de deux éléments: les gardes et les fournisseurs.

Dans cette section, nous allons créer un fournisseur d'authentification qui traite de la récupération des utilisateurs à partir du serveur principal.

Allez-y et créez un fichier app/Extensions/MongoUserProvider.php comme indiqué ci-dessous.

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
}

Là encore, vous devez vous assurer que le fournisseur personnalisé doit implémenter le contrat Illuminate\Contracts\Auth\UserProvider.

Pour aller de l'avant, il définit deux méthodes importantes: retrieveByCredentials et validateCredentials.

La méthode retrieveByCredentials permet de récupérer les informations d'identification de l'utilisateur à l'aide de la classe de modèle User décrite dans la section précédente. D'autre part, la méthode validateCredentials est utilisée pour valider un utilisateur par rapport à l'ensemble d'identifiants donné.

Et ce fut la mise en œuvre de notre fournisseur d'authentification personnalisé. Dans la section suivante, nous allons créer une protection qui interagit avec le fournisseur d'authentification MongoUserProvider.

Configurer la garde d'authentification

Comme nous en avons discuté précédemment, le système de protection du système d’authentification de Laravel définit le mode d’authentification de l’utilisateur. Dans notre cas, nous vérifierons la présence du paramètre de requête jsondata qui devrait contenir la chaîne codée JSON des informations d'identification.

Dans cette section, nous allons créer une protection qui interagit avec le fournisseur d'authentification créé dans la dernière section.

Allez-y et créez un fichier app/Services/Auth/JsonGuard.php avec le contenu suivant.

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
}

Tout d’abord, notre classe doit implémenter l’interface Illuminate\Contracts\Auth\Guard. Il faut donc définir toutes les méthodes déclarées dans cette interface.

Il est important de noter ici que la fonction __construct nécessite une implémentation de Illuminate\Contracts \Auth\UserProvider. Dans notre cas, nous allons passer une instance de App\Extensions\MongoUserProvider, comme nous le verrons dans la section ultérieure.

Ensuite, il existe une fonction getJsonParams qui récupère les informations d'identification de l'utilisateur à partir du paramètre de requête nommé jsondata. Comme nous nous attendons à recevoir une chaîne codée JSON des informations d'identification de l'utilisateur, nous avons utilisé la fonction json_decode pour décoder les données JSON.

Dans la fonction validate, la première chose que nous vérifions est l’existence de l’argument $credentials. S'il n'est pas présent, nous appelons la méthode getJsonParams pour récupérer les informations d'identification de l'utilisateur à partir des paramètres de la demande.

Ensuite, nous appelons la méthode retrieveByCredentials du fournisseur MongoUserProvider qui extrait l'utilisateur à partir de la base de données MongoDB. Enfin, c'est la méthode validateCredentials du fournisseur MongoUserProvider qui vérifie la validité de l'utilisateur.

C'était donc la mise en œuvre de notre garde de douane. La section suivante explique comment assembler ces éléments pour former un système d’authentification réussi.

Mettre tous ensemble

Jusqu'à présent, nous avons développé tous les éléments de la protection d'authentification personnalisée qui devrait nous fournir un nouveau système d'authentification. Cependant, cela ne fonctionnera pas immédiatement car nous devons d'abord l'enregistrer à l'aide des liaisons du conteneur de services Laravel.

Comme vous le savez sûrement déjà, le fournisseur de services Laravel est le bon endroit pour mettre en œuvre les liaisons nécessaires.

Allez-y et ouvrez le fichier app/Providers/AuthServiceProvider.php qui nous permet d’ajouter des liaisons de conteneur de service d’authentification. S'il ne contient aucune modification personnalisée, vous pouvez simplement le remplacer par le contenu suivant.

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
}

Passons en revue la méthode boot qui contient la plupart des liaisons du fournisseur.

Pour commencer, nous allons créer des liaisons pour les éléments App\Database\MongoDatabase et 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
});

Cela fait un moment que nous parlons de fournisseur et de gardien, et il est temps de brancher notre garde personnalisée au système d'authentification Laravel.

Nous avons utilisé la méthode de fournisseur de Auth Facade pour ajouter notre fournisseur d'authentification personnalisé sous la clé Mongo. Rappelez-vous que la clé reflète les paramètres ajoutés précédemment dans le fichier auth.php.

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

De la même manière, nous allons injecter notre implémentation Guard personnalisée en utilisant la méthode extend de la façade Auth.

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

Nous avons ensuite utilisé une méthode de registre pour lier l'interface App\Services\Contracts\NosqlServiceInterface à l'implémentation App\Database\MongoDatabase.

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

Ainsi, chaque fois qu'il est nécessaire de résoudre la dépendance App\Services\Contracts\NosqlServiceInterface, Laravel répond en implémentant l'adaptateur App\Database\MongoDatabase.

L'avantage d'utiliser cette approche est que l'on peut facilement échanger l'implémentation donnée avec une implémentation personnalisée. Par exemple, supposons que quelqu'un souhaite remplacer l'implémentation App\Database\MongoDatabase par l'adaptateur CouchDB. Dans ce cas, il leur suffit d'ajouter la liaison correspondante dans la méthode register.

C'était donc le fournisseur de services à votre disposition. À l'heure actuelle, nous disposons de tout le nécessaire pour tester notre implémentation de protection personnalisée. La section suivante, qui porte sur la conclusion, traite de ce sujet.

Est-ce que ça marche?

Vous avez travaillé d'arrache-pied pour configurer votre première protection d'authentification personnalisée et il est maintenant temps de tirer parti des avantages qui s'offrent à vous et d'essayer.

Implémentons rapidement un fichier de contrôleur assez basique app/Http/Controllers/MongoController.php comme indiqué ci-dessous.

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
}

Examinez de près la dépendance de la méthode de connexion, qui nécessite l'implémentation de la protection Illuminate\Contracts\Auth\Guard. Puisque nous avons défini la garde personnalisée comme garde par défaut dans le fichier auth.php, c'est App\Services\Auth\JsonGuard qui va être injecté!

Ensuite, nous avons appelé la méthode validate de la classe App\Services\Auth\JsonGuard, qui à son tour initie une série d'appels de méthode:

  • Il appelle la méthode retrieveByCredentials de la classe App\Extensions\MongoUserProvider.
  • La méthode retrieveByCredentials appelle la méthode fetchUserByCredentials de la classe User App\Models\Auth\User.
  • La méthode fetchUserByCredentials appelle la méthode find de App\Database\MongoDatabase pour récupérer les informations d'identification de l'utilisateur.
  • Enfin, la méthode find de App\Database\MongoDatabase renvoie la réponse!

Si tout fonctionne comme prévu, nous devrions obtenir un utilisateur authentifié en appelant la méthode user de notre gardien.

Pour accéder au contrôleur, vous devez ajouter une route associée dans le fichier routes/web.php.

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

Essayez d’accéder à l’URL http://votre-site-laravel/custom/mongo/login sans passer aucun paramètre et vous devriez voir un message "non autorisé".

D'autre part, essayez quelque chose comme http://votre-site-laravel/custom/mongo/login?Jsondata={"username": "admin", "password": "admin"} et qui devrait renvoyer un message de réussite. si l'utilisateur est présent dans votre base de données.

Veuillez noter qu'il ne s'agit que d'exemples illustrant le fonctionnement de la protection personnalisée. Vous devez implémenter une solution infaillible pour une fonctionnalité telle que la connexion. En fait, je viens de donner un aperçu du flux d'authentification; vous êtes responsable de la création d'une solution robuste et sécurisée pour votre application.

Cela met fin à notre voyage d’aujourd’hui et j'espère pouvoir revenir avec des informations plus utiles. Si vous souhaitez que j'écrive sur un sujet spécifique, n'oubliez pas de m'envoyer un message!

Conclusion

Le framework Laravel fournit un système d’authentification solide dans le noyau qui peut être étendu si vous souhaitez implémenter un système personnalisé. C'était le sujet de l'article d'aujourd'hui visant à implémenter une protection personnalisée et à la brancher au flux de travaux d'authentification Laravel.

Au cours de cette opération, nous avons mis au point un système qui authentifie l'utilisateur sur la base de la charge utile JSON de la demande et le met en correspondance avec la base de données MongoDB. Et pour y parvenir, nous avons créé une protection personnalisée et une implémentation de fournisseur personnalisée.

J'espère que l'exercice vous a fourni des informations sur le processus d'authentification de Laravel et que vous devriez maintenant vous sentir plus confiant quant à son fonctionnement interne.

Pour ceux d'entre vous qui débutent avec Laravel ou qui souhaitent développer leurs connaissances, leur site ou leur application avec des extensions, nous pouvons étudier de nombreuses choses sur le marché Envato.

J'aimerais entendre vos commentaires et suggestions, alors criez fort en utilisant le flux ci-dessous!

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.