Advertisement
  1. Code
  2. PHP

Erstellen eines benutzerdefinierten Authentifizierungswächters in Laravel

Scroll to top
Read Time: 18 min

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

In diesem Artikel behandeln wir das Authentifizierungssystem im Laravel-Framework. Das Hauptziel dieses Artikels besteht darin, einen benutzerdefinierten Authentifizierungswächter zu erstellen, indem das Kernauthentifizierungssystem erweitert wird.

Laravel bietet ein sehr solides Authentifizierungssystem im Kern, das die Implementierung der Standardauthentifizierung zum Kinderspiel macht. In der Tat müssen Sie nur ein paar handwerkliche Befehle ausführen, um das Gerüst eines Authentifizierungssystems einzurichten.

Darüber hinaus ist das System selbst so konzipiert, dass Sie es erweitern und Ihre eigenen Authentifizierungsadapter anschließen können. Das werden wir in diesem Artikel ausführlich besprechen. Bevor wir mit der Implementierung des benutzerdefinierten Authentifizierungs-Wächters beginnen, beginnen wir mit einer Diskussion der grundlegenden Elemente im Laravel-Authentifizierungssystem - Wächter und Anbieter.

Die Kernelemente: Wächter und Anbieter

Das Laravel-Authentifizierungssystem besteht aus zwei Elementen in seinen Kernwachen und -anbietern.

Wächter

Sie könnten sich einen Wächter vorstellen, um die Logik zu liefern, mit der die authentifizierten Benutzer identifiziert werden. Im Kern bietet Laravel verschiedene Wachen wie Session und Token. Der Sitzungswächter behält den Zustand des Benutzers bei jeder Anfrage durch Cookies bei, und andererseits authentifiziert der Berechtigungswächter den Benutzer, indem er bei jeder Anfrage ein gültiges Token überprüft.

Wie Sie sehen können, definiert der Wächter also die Logik der Authentifizierung. Es muss nicht immer mit dieser Sicherheit umgehen, indem gültige Anmeldeinformationen vom Back-End abgerufen werden. Sie können einen Wächter implementieren, der einfach das Vorhandensein eines bestimmten Objekts in Anforderungsheadern überprüft und Benutzer basierend darauf authentifiziert.

Später in diesem Artikel implementieren wir einen Wächter, der bestimmte JSON-Parameter in Anforderungsheadern überprüft und den gültigen Benutzer vom MongoDB-Back-End abruft.

Anbieter

Wenn der Wächter die Logik der Authentifizierung definiert, ist der Authentifizierungsanbieter dafür verantwortlich, den Benutzer aus dem Back-End-Speicher abzurufen. Wenn der Schutz erfordert, dass der Benutzer gegen den Back-End-Speicher validiert werden muss, dann geht die Implementierung des Abrufens des Benutzers in den Authentifizierungsanbieter.

Laravel wird mit zwei Standard-Authentifizierungsanbietern geliefert: Datenbank und Eloquent. Der Datenbankauthentifizierungsanbieter befasst sich mit dem einfachen Abrufen der Benutzeranmeldeinformationen aus dem Back-End-Speicher, während Eloquent eine Abstraktionsschicht bereitstellt, die das Notwendige tut.

In unserem Beispiel implementieren wir einen MongoDB-Authentifizierungsanbieter, der die Benutzeranmeldeinformationen vom MongoDB-Back-End abruft.

Das war eine grundlegende Einführung in die Wächter und Anbieter des Laravel-Authentifizierungssystems. Ab dem nächsten Abschnitt konzentrieren wir uns auf die Entwicklung des Custom Authentication Guards und Providers!

Ein kurzer Blick auf das Datei-Setup

Werfen wir einen kurzen Blick auf die Liste der Dateien, die wir im Verlauf dieses Artikels implementieren werden.

  • config/auth.php: Es ist die Authentifizierungs-Konfigurationsdatei, in der wir einen Eintrag unseres benutzerdefinierten Schutzes hinzufügen.
  • config/mongo.php: Es ist die Datei, die die MongoDB-Konfiguration enthält.
  • app/Services/Contracts/NosqlServiceInterface.php: Es ist eine Schnittstelle, die unsere benutzerdefinierte Mongo-Datenbank-Klasse implementiert.
  • app / Database / MongoDatabase.php: Dies ist eine Hauptdatenbankklasse, die mit MongoDB interagiert.
  • app/Models/Auth/User.php: Es ist die Benutzermodellklasse, die den Authenticable-Vertrag implementiert.
  • app/Extensions/MongoUserProvider.php: Es ist eine Implementierung des Authentifizierungsanbieters.
  • app/Services/Auth/JsonGuard.php: Es ist eine Implementierung des Authentifizierungs-Wächter-Treibers.
  • app/Providers/AuthServiceProvider.php: Dies ist eine vorhandene Datei, die wir zum Hinzufügen unserer Service-Container-Bindungen verwenden.
  • app/Http/Controller/MongoController.php: Es ist eine Demo-Controller-Datei, die wir implementieren, um unsere benutzerdefinierte Wache zu testen.

Machen Sie sich keine Sorgen, wenn die Liste der Dateien noch nicht viel Sinn ergibt, da wir alles im Detail besprechen werden, während wir es durchgehen.

Tief tauchen in die Umsetzung

In diesem Abschnitt werden wir die Implementierung der erforderlichen Dateien durchführen.

Das erste, was wir tun müssen, ist, Laravel über unseren Wachmann zu informieren. Fahren Sie fort und geben Sie die benutzerdefinierten Guard-Details in der Datei config/auth.php wie gezeigt ein.

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

Wie Sie sehen können, haben wir unseren benutzerdefinierten Schutz unter dem benutzerdefinierten Schlüssel hinzugefügt.

Als Nächstes müssen wir im Abschnitt "Provider" einen zugehörigen Providereintrag hinzufügen.

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

Wir haben unseren Anbietereintrag unter dem Mongo Key hinzugefügt.

Schließlich, lassen Sie uns den Standardauthentifizierungsschutz von Web zu Gewohnheit ändern.

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

Natürlich wird es noch nicht funktionieren, da wir die notwendigen Dateien noch nicht implementiert haben. Und das werden wir in den nächsten Abschnitten besprechen.

Richten Sie den MongoDB-Treiber ein

In diesem Abschnitt implementieren wir die notwendigen Dateien, die mit der zugrunde liegenden MongoDB-Instanz kommunizieren.

Lassen Sie uns zunächst eine Konfigurationsdatei config / mongo.php erstellen, die die standardmäßigen MongoDB-Verbindungseinstellungen enthält.

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

Natürlich müssen Sie die Platzhalterwerte gemäß Ihren Einstellungen ändern.

Anstatt direkt eine Klasse zu erstellen, die mit MongoDB interagiert, erstellen wir zuerst eine Schnittstelle.

Der Vorteil der Erstellung einer Schnittstelle besteht darin, dass sie einen Vertrag bereitstellt, den ein Entwickler während seiner Implementierung einhalten muss. Außerdem könnte unsere Implementierung von MongoDB bei Bedarf problemlos durch eine andere NoSQL-Implementierung ersetzt werden.

Machen Sie weiter und erstellen Sie eine Interface-Datei app/Services/Contracts/NosqlServiceInterface.php mit folgendem Inhalt.

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 ist eine ziemlich einfache Schnittstelle, die die grundlegenden CRUD-Methoden deklariert, die eine Klasse definieren muss, die diese Schnittstelle implementiert.

Definieren wir nun eine tatsächliche Klasse in 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
}

Natürlich gehe ich davon aus, dass Sie MongoDB und die dazugehörige MongoDB PHP-Erweiterung installiert haben.

Die __construct-Methode instanziiert die MongoClient-Klasse mit den erforderlichen Parametern. Die andere wichtige Methode, an der wir interessiert sind, ist die find-Methode, die den Datensatz basierend auf den als Methodenargumenten bereitgestellten Kriterien abruft.

Das war also die Implementierung des MongoDB-Treibers, und ich habe versucht, es so einfach wie möglich zu halten.

Richten Sie das Benutzermodell ein

Im Einklang mit den Standards des Authentifizierungssystems müssen wir das Benutzermodell implementieren, das den Vertrag Illuminate\Contracts\Auth\Authenticatable implementieren muss.

Gehen Sie voran und erstellen Sie eine Datei-app/Models/Auth/User.php mit den folgenden Inhalten.

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
}

Sie sollten bereits bemerkt haben, dass App\Models\Auth\User den Illuminate\Contracts\ Auth\Authenticatable-Vertrag implementiert.

Die meisten in unserer Klasse implementierten Methoden sind selbsterklärend. Allerdings haben wir die Methode fetchUserByCredentials definiert, die den Benutzer vom verfügbaren Backend abruft. In unserem Fall handelt es sich um eine MongoDatabase-Klasse, die aufgerufen wird, um die erforderlichen Informationen abzurufen.

Das ist also die Implementierung des Benutzermodells.

Richten Sie den Authentifizierungsanbieter ein

Wie bereits erwähnt, besteht das Laravel-Authentifizierungssystem aus zwei Elementen - Wächtern und Anbietern.

In diesem Abschnitt erstellen wir einen Authentifizierungsanbieter, der sich mit dem Benutzerabruf vom Back-End befasst.

Gehen Sie voran und erstellen Sie eine Datei-app/Extensions/MongoUserProvider.php wie unten gezeigt.

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
}

Auch hier müssen Sie sicherstellen, dass der benutzerdefinierte Anbieter den Vertrag Illuminate\Contracts\Auth\UserProvider implementieren muss.

Im weiteren Verlauf definiert es zwei wichtige Methoden - retrieveByCredentials und validateCredentials.

Die retrieveByCredentials-Methode wird verwendet, um die Benutzeranmeldeinformationen mithilfe der Benutzermodellklasse abzurufen, die im vorherigen Abschnitt behandelt wurde. Auf der anderen Seite wird die validateCredentials-Methode verwendet, um einen Benutzer anhand der angegebenen Anmeldeinformationen zu validieren.

Und das war die Implementierung unseres benutzerdefinierten Authentifizierungsanbieters. Im nächsten Abschnitt werden wir einen Wächter erstellen, der mit dem MongoUserProvider-Authentifizierungsanbieter interagiert.

Richten Sie den Authentifizierungsschutz ein

Wie bereits erwähnt, legt der Wächter im Laravel-Authentifizierungssystem fest, wie der Benutzer authentifiziert wird. In unserem Fall überprüfen wir das Vorhandensein des jsondata-Anforderungsparameters, der die JSON-codierte Zeichenfolge der Anmeldeinformationen enthalten sollte.

In diesem Abschnitt erstellen wir einen Wächter, der mit dem Authentifizierungsanbieter interagiert, der gerade im letzten Abschnitt erstellt wurde.

Gehen Sie voran und erstellen Sie eine Datei-app/Services/Auth/JsonGuard.php mit den folgenden Inhalten.

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
}

Zuallererst muss unsere Klasse die Schnittstelle Illuminate\Contracts\Auth\Guard implementieren. Daher müssen wir alle Methoden definieren, die in dieser Schnittstelle deklariert sind.

Beachten Sie hier, dass die __construct-Funktion eine Implementierung von Illuminate\Contracts\Auth\UserProvider erfordert. In unserem Fall übergeben wir eine Instanz von App\Extensions\MongoUserProvider, wie wir im späteren Abschnitt sehen werden.

Als nächstes gibt es eine Funktion getJsonParams, die die Benutzeranmeldeinformationen vom Anforderungsparameter jsondata abruft. Da erwartet wird, dass wir eine JSON-codierte Zeichenfolge der Benutzeranmeldeinformationen erhalten, haben wir die json_decode-Funktion zum Decodieren der JSON-Daten verwendet.

In der Validierungsfunktion überprüfen wir als erstes, ob das Argument $credentials vorhanden ist. Wenn es nicht vorhanden ist, rufen wir die getJsonParams-Methode auf, um Benutzeranmeldeinformationen aus den Anforderungsparametern abzurufen.

Als Nächstes rufen wir die Methode retrieveByCredentials des MongoUserProvider-Anbieters auf, die den Benutzer aus dem Back-End der MongoDB-Datenbank abruft. Schließlich überprüft die validateCredentials-Methode des MongoUserProvider-Anbieters die Gültigkeit des Benutzers.

Das war also die Umsetzung unserer Wachmannschaft. Im nächsten Abschnitt wird beschrieben, wie diese Teile zu einem erfolgreichen Authentifizierungssystem zusammengefügt werden.

Alles zusammenfügen

Bis jetzt haben wir alle Elemente des Custom Authentication Guards entwickelt, die uns ein neues Authentifizierungssystem zur Verfügung stellen sollten. Es funktioniert jedoch nicht sofort, da wir es zuerst mit den Laravel Service Container Bindings registrieren müssen.

Wie Sie bereits wissen sollten, ist der Laravel Service Provider der richtige Ort, um die notwendigen Bindungen zu implementieren.

Gehen Sie voran und öffnen Sie die Datei app/Providers/AuthServiceProvider.php, die es uns erlaubt, Container Bindings des Authentifizierungsdienstes hinzuzufügen. Wenn es keine benutzerdefinierten Änderungen enthält, können Sie es einfach durch den folgenden Inhalt ersetzen.

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
}

Lassen Sie uns die boot-Methode durchlaufen, die die meisten Provider-Bindungen enthält.

Zunächst erstellen wir Bindungen für die Elemente App\Database\MongoDatabase und 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
});

Es ist schon eine Weile her, dass wir über Provider und Wächter gesprochen haben, und es ist Zeit, unseren eigenen Wächter in das Laravel-Authentifizierungssystem zu stecken.

Wir haben die Provider-Methode der Auth Facade verwendet, um unseren benutzerdefinierten Authentifizierungsanbieter unter dem Schlüssel mongo hinzuzufügen. Erinnern Sie sich, dass der Schlüssel die Einstellungen widerspiegelt, die zuvor in der Datei auth.php hinzugefügt wurden.

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

In ähnlicher Weise werden wir unsere Custom-Guard-Implementierung mit der extend-Methode der Auth-Fassade einfügen.

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

Als Nächstes gibt es eine register-Methode, mit der wir die App\Services\Contracts\NosqlServiceInterface-Schnittstelle an die App\Database\MongoDatabase-Implementierung gebunden haben.

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

Wann immer die Abhängigkeit von App\Services\Contracts\NosqlServiceInterface aufgelöst werden muss, antwortet Laravel mit der Implementierung des App\Database\MongoDatabase-Adapters.

Der Vorteil bei der Verwendung dieses Ansatzes besteht darin, dass die gegebene Implementierung leicht durch eine benutzerdefinierte Implementierung ersetzt werden kann. Angenommen, jemand möchte die App\Database\MongoDatabase-Implementierung in Zukunft durch den CouchDB-Adapter ersetzen. In diesem Fall müssen sie nur die entsprechende Bindung in der Registermethode hinzufügen.

Das war also der Dienstleister, der Ihnen zur Verfügung stand. In diesem Moment haben wir alles, was erforderlich ist, um unsere Custom-Guard-Implementierung zu testen, also geht es im nächsten und abschließenden Abschnitt darum.

Funktioniert es?

Sie haben die ganze Arbeit damit getan, Ihren ersten benutzerdefinierten Authentifizierungswächter einzurichten, und jetzt ist es an der Zeit, die Vorteile zu nutzen, während wir weitermachen und es versuchen werden.

Lassen Sie uns schnell eine ziemlich einfache Controller-Datei-App/Http/Controllers/MongoController.php wie unten gezeigt implementieren.

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
}

Sehen Sie sich die Abhängigkeit der Anmeldemethode genau an, die die Implementierung des Befehls Illuminate\Contracts\Auth\Guard erfordert. Da wir den benutzerdefinierten Wächter als Standardwächter in der Datei auth.php eingestellt haben, wird die App\Services\Auth\JsonGuard tatsächlich injiziert!

Als Nächstes haben wir die validate-Methode der App\Services\Auth\JsonGuard-Klasse aufgerufen, die wiederum eine Reihe von Methodenaufrufen einleitet:

  • Es ruft die retrieveByCredentials-Methode der App\Extensions\MongoUserProvider-Klasse auf.
  • Die Methode retrieveByCredentials ruft die Methode fetchUserByCredentialsder Klasse User App\Models\Auth\Userauf.
  • Die fetchUserByCredentials-Methode ruft die find-Methode der App\Database\MongoDatabase auf, um die Benutzeranmeldeinformationen abzurufen.
  • Schließlich gibt die Methode find der App\Database\MongoDatabase die Antwort zurück!

Wenn alles wie erwartet funktioniert, sollten wir einen authentifizierten Benutzer erhalten, indem wir die user-Methode unserer Wache aufrufen.

Um auf den Controller zuzugreifen, sollten Sie eine zugehörige Route in der Datei routes/web.php hinzufügen.

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

Versuchen Sie, auf die URL http://your-laravel-site /custom/mongo /login zuzugreifen, ohne irgendwelche Parameter zu übergeben, und Sie sollten eine "nicht autorisierte" Nachricht sehen.

Auf der anderen Seite, versuchen Sie etwas wie http://Ihre-Laravel-Site/Benutzerdefiniert/Mongo/Login?Jsondata={"Benutzername": "admin", "password": "admin"} und das sollte eine Erfolgsmeldung zurückgeben wenn der Benutzer in Ihrer Datenbank vorhanden ist.

Bitte beachten Sie, dass dies nur zu Beispielzwecken ist, um zu demonstrieren, wie der Zollschutz funktioniert. Sie sollten eine narrensichere Lösung für ein Feature wie Login implementieren. In der Tat habe ich nur einen Einblick in den Authentifizierungsablauf gegeben; Sie sind dafür verantwortlich, eine robuste und sichere Lösung für Ihre Anwendung zu entwickeln.

Damit endet unsere Reise heute, und hoffentlich komme ich mit nützlicherem Zeug zurück. Wenn Sie möchten, dass ich zu bestimmten Themen schreibe, vergessen Sie nicht, mir eine Nachricht zu schicken!

Fazit

Das Laravel-Framework bietet ein solides Authentifizierungssystem im Kern, das erweitert werden könnte, wenn Sie ein benutzerdefiniertes System implementieren möchten. Das war das Thema des heutigen Artikels, um einen benutzerdefinierten Wächter zu implementieren und ihn mit dem Laravel-Authentifizierungs-Workflow zu verbinden.

In diesem Zuge haben wir ein System entwickelt, das den Benutzer basierend auf den JSON-Nutzdaten in der Anfrage authentifiziert und mit der MongoDB-Datenbank abgleicht. Um dies zu erreichen, haben wir am Ende einen benutzerdefinierten Guard und eine benutzerdefinierte Provider-Implementierung erstellt.

Ich hoffe, die Übung hat Ihnen einen Einblick in den Laravel-Authentifizierungsfluss gegeben, und Sie sollten sich jetzt sicherer in Bezug auf die inneren Abläufe fühlen.

Für diejenigen unter Ihnen, die gerade mit Laravel anfangen oder Ihr Wissen, Ihre Website oder Ihre Anwendung mit Erweiterungen erweitern möchten, haben wir eine Vielzahl von Dingen, die Sie auf Envato Market studieren können.

Ich würde gerne Ihre Rückmeldungen und Vorschläge hören, also schreien Sie laut mit dem Feed unten!

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.