Advertisement
  1. Code
  2. PHP

Как создать кастомную аутентификацию в Laravel

Scroll to top
Read Time: 17 min

Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)

В этой статье мы рассмотрим систему аутентификации в рамках Laravel. Основная цель этой статьи - создать настраиваемый защитный механизм аутентификации путем расширения базовой системы аутентификации.

Laravel в своем ядре обеспечивает очень прочную систему аутентификации, что делает внедрение базовой аутентификации совсем простым. На самом деле вам просто нужно запустить пару artisan команд, чтобы настроить каркас системы аутентификации.

Более того, сама система разработана таким образом, что вы можете ее расширить и подключить к своим адаптерам аутентификации. Это то, что мы подробно обсудим в этой статье. Прежде чем мы перейдем к внедрению специального средства проверки подлинности, мы начнем с обсуждения основных элементов аутентификации и ее провайдеров в Laravel.

Основные элементы: гуарды и провайдеры

Система аутентификации Laravel состоит из двух элементов в своем ядре: гуарды и провайдеры.

Гуарды

Гуард можно рассматривать как способе подачи логики, которая используется для идентификации пользователей, прошедших проверку аутентификации. В основе Laravel предоставляет различные гуарды, такие как сессия и токен. Гуард сессии поддерживает состояние пользователя в каждом запросе с помощью файлов cookie, а с другой стороны гуард токена аутентифицирует пользователя, проверяя действительный токен в каждом запросе.

Итак, как вы можете видеть, гуард определяет логику аутентификации, и нет необходимости, чтобы он всегда справлялся с этим, выбирая действительные учетные данные из вашего бэкенда. Вы можете реализовать гуард, который просто проверяет наличие определенной вещи в заголовках запросов и аутентифицирует пользователей на основе этого.

Позже в этой статье мы будем внедрять гуард, который проверяет определенные параметры JSON в заголовках запроса и извлекает валидного пользователя из MongoDB.

Провайдеры

Если гуард определяет логику аутентификации, поставщик аутентификации отвечает за извлечение пользователя из внутреннего хранилища. Если гуард требует, чтобы пользователь был проверен против внутреннего хранилища, тогда реализация запроса пользователя переходит в поставщика проверки подлинности.

Laravel поставляется с двумя поставщиками аутентификации по умолчанию - Database and Eloquent. Поставщик аутентификации базы данных имеет дело с прямым поиском учетных данных пользователя из внутреннего хранилища, в то время как Eloquent предоставляет уровень абстракции, который делает это необходимым.

В нашем примере мы реализуем поставщика аутентификации MongoDB, который извлекает учетные данные пользователя  MongoDB.

Итак, это было базовое введение в гуардов и провайдеров в системе аутентификации Laravel. В следующем разделе мы сосредоточимся на разработке кастомных гуарда и поставщика!

Быстрый взгляд на настройку файлов

Давайте быстро рассмотрим список файлов, которые мы будем использовать на протяжении этой статьи.

  • config/auth.php: Это файл конфигурации аутентификации, в который мы добавим запись нашего пользовательского гуарда.
  • config/mongo.php: Это файл, содержащий конфигурацию MongoDB.
  • app/Services/Contracts/NosqlServiceInterface.php: Это интерфейс, который реализует наш пользовательский класс базы данных Mongo.
  • app/Database/MongoDatabase.php: Это основной класс базы данных, который взаимодействует с MongoDB.
  • app/Models/Auth/User.php: Это класс модели пользователя, который реализует контракт Authenticable.
  • app/Extensions/MongoUserProvider.php: Это реализация поставщика проверки подлинности.
  • app/Services/Auth/JsonGuard.php: Это реализация драйвера гуарда аутентификации.
  • app/Providers/AuthServiceProvider.php: Это уже существующий файл, который мы будем использовать для добавления привязок контейнера нашего сервиса.
  • app/Http/Controllers/MongoController.php: Это файл демонстрационного контроллера, который мы будем создавать, чтобы протестировать наш пользовательский гуард.

Не беспокойтесь, если данный список файлов пока для вас не поняет, поскольку скоро мы подробно обсудим его.

Погружение в реализацию

В этом разделе мы рассмотрим реализацию необходимых файлов.

Первое, что нам нужно сделать, это сообщить Laravel о нашем кастомном гуарде. Идем дальше и добавляем данные кастомного гуарда в файл config/auth.php, как показано нижн.

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

Как вы можете видеть, мы добавили наш кастомный гуард под специальным ключом custom.

Затем нам нужно добавить соответствующую запись провайдера в разделе providers.

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

Мы добавили запись нашего провайдера под ключом mongo.

Наконец, давайте изменим гуард аутентификации по умолчанию с web на custom.

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

Конечно, пока это не сработает, поскольку мы еще не реализовали необходимые файлы. И об этом мы поговорим в следующих разделах.

Настройка драйвера MongoDB

В этом разделе мы будем реализовывать необходимые файлы, которые общаются с базовым экземпляром MongoDB.

Сначала создадим конфигурационный файл config/mongo.php, который содержит настройки соединения MongoDB по умолчанию.

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

Конечно, вам нужно изменить значения заполнителя в соответствии с вашими настройками.

Вместо прямого создания класса, который взаимодействует с MongoDB, мы в первую очередь создадим интерфейс.

Преимущество создания интерфейса заключается в том, что он предоставляет контракт, которого разработчик должен придерживаться при его реализации. Кроме того, наша реализация MongoDB может быть легко заменена другой версией NoSQL, если это необходимо.

Идем дальше и создаем файла интерфейса app/Services/Contracts/NosqlServiceInterface.php со следующим содержимым.

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
}

Это довольно простой интерфейс, который объявляет базовые методы CRUD, которые должен определить класс, реализующий этот интерфейс.

Теперь давайте определим фактический класс в 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
}

Конечно, я предполагаю, что вы установили MongoDB и соответствующее расширение PHP MongoDB.

Метод __construct создает экземпляр класса MongoClient с необходимыми параметрами. Другим важным методом, который нас интересует, является метод find, который извлекает запись на основе критериев, предоставленных в качестве аргументов метода.

Такого была реализация драйвера MongoDB, и я старался максимально упростить его.

Настройка модели пользователя

Соблюдая стандарты системы аутентификации, нам необходимо реализовать модель User, которая должна реализовать контракт Illuminate\Contracts\Auth\Authenticatable.

Двигаемся дальше и создаем файл app/Models/Auth/User.php  со следующим содержимым.

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
}

Вы должны были заметить, что App\Models\Auth\User реализует контракт Illuminate\Contracts\Auth\Authenticatable.

Большинство методов, реализованных в нашем классе, не требуют пояснений. Имея это в виду, мы определили метод fetchUserByCredentials, который извлекает пользователя. В нашем случае это будет класс MongoDatabase, который будет вызываться для извлечения необходимой информации.

Итак, это реализация модели User.

Настройка провайдера аутентификации

Как мы обсуждали ранее, система аутентификации Laravel состоит из двух элементов - гуардов и провайдеров.

В этом разделе мы создадим провайдера аутентификации, который занимается поиском пользователя на бэкенде.

Двигаемся дальше и создаем файл app/Extensions/MongoUserProvider.php, как показано ниже.

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
}

Опять же, вам нужно убедиться, что пользовательский провайдер должен реализовать контракт Illuminate\Contracts\Auth\UserProvider.

Двигаясь вперед, он определяет два важных метода: retrieveByCredentials и validateCredentials.

Метод retrieveByCredentials используется для извлечения учетных данных пользователя с использованием класса модели User, который обсуждался в предыдущем разделе. С другой стороны, метод validateCredentials используется для проверки пользователя с использованием данного набора учетных данных.

И это была реализация нашего пользовательского провайдера аутентификации. В следующем разделе мы продолжим работу и создаем гуарда, который взаимодействует с провайдеров аутентификации MongoUserProvider.

Настройка гуарда аутентификации

Как мы обсуждали ранее, гуард в системе аутентификации Laravel устанавливает, как пользователь аутентифицируется. В нашем случае мы проверим наличие параметра запроса jsondata, который должен содержать строку учетных данных, кодированную JSON.

В этом разделе мы создадим гуарда, который взаимодействует с провайдеров аутентификации, который был только что создан в последнем разделе.

Далее создайте файл app/Services/Auth/JsonGuard.php  со следующим содержимым.

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
}

Прежде всего, нашему классу необходимо реализовать интерфейс Illuminate\Contracts\Auth\Guard. Таким образом, нам нужно определить все методы, объявленные в этом интерфейсе.

Важно отметить, что функция __construct требует реализации Illuminate\Contracts\Auth\UserProvider. В нашем случае мы передадим экземпляр App\Extensions\MongoUserProvider.

Далее, есть функция getJsonParams, которая извлекает учетные данные пользователя из параметра запроса с именем jsondata. Поскольку ожидается, что мы получим кодированную строку JSON учетных данных пользователя, мы использовали функцию json_decode для декодирования данных JSON.

В функции validate первое, что мы проверяем, это наличие аргумента $credentials. Если этого нет, мы вызываем метод getJsonParams для получения учетных данных пользователя из параметров запроса.

Затем мы вызываем метод retrieveByCredentials провайдера MongoUserProvider, который извлекает пользователя из базы данных MongoDB. Наконец, метод validateCredentials провайдера MongoUserProvider проверяет валидность User.

Итак, это была реализация нашего кастомного гуарда. В следующем разделе описывается, как соединить эти фрагменты вместе, чтобы сформировать успешную систему аутентификации.

Все вместе

До сих пор мы разработали все элементы кастомного гуарда аутентификации, которые должны предоставить нам новую систему аутентификации. Однако он не будет работать из коробки, поскольку мы должны сначала зарегистрировать его, используя привязки сервисов в контейнере Laravel.

Как вы уже должны знать, провайдер услуг Laravel является правильным местом для реализации необходимых привязок.

Откройте файл app/Providers/AuthServiceProvider.php, который позволяет нам добавлять привязки гуардов. Если он не содержит каких-либо пользовательских изменений, вы можете просто заменить его следующим содержимым.

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
}

Давайте рассмотрим метод boot, который содержит большинство привязок провайдера.

Для начала создадим привязки для элементов App\Database\MongoDatabase и 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
});

Прошло некоторое время, когда мы говорили о провайдере и охранниках, и пришло время подключить наш собственный гуард к системе аутентификации Laravel.

Мы использовали метод провайдера Auth Facade для добавления нашего кастомного гуадра аутентификации по ключу mongo. Напомним, что ключ отражает параметры, которые были добавлены ранее в файл auth.php.

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

Аналогичным образом мы будем внедрять наш кастомный гуард, используя метод extend фасада Auth.

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

Далее, существует метод register, который мы использовали для привязки интерфейса App\Services\Contracts\NosqlServiceInterface к реализации App\Database\MongoDatabase.

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

Поэтому всякий раз, когда возникает необходимость в разрешении зависимости App\Services\Contracts\NosqlServiceInterface, Laravel отвечает реализацией адаптера App\Database\MongoDatabase.

Преимущество использования этого подхода заключается в том, что можно легко подменить данную реализацию своей кастомной. Например, скажем, кто-то хотел бы заменить реализацию App\Database\MongoDatabase адаптером CouchDB в будущем. В этом случае им просто нужно добавить соответствующую привязку в методе register.

Так что это был поставщик услуг в вашем распоряжении. На данный момент у нас есть все, что требуется для проверки нашей реализации пользовательского гуарда, поэтому следующий и заключительный раздел будет об этом.

А это вообще работает?

Вы проделали всю тяжелую работу, настроив свой первый кастомный гуард аутентификации, и теперь пришло время воспользоваться его преимуществами.

Давайте быстро реализуем простой базовый контроллер app/Http/Controllers/MongoController.php, как показано ниже.

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
}

Внимательно посмотрите на зависимость метода login в систему, для чего требуется реализация гуарда Illuminate\Contracts\Auth\Guard. Поскольку в файле auth.php установлен custom гуард в качестве гуарда по умолчанию, то будет использоваться файл App\Services\Auth\JsonGuard.

Затем мы вызываем метод validate класса App\Services\Auth\JsonGuard, который, в свою очередь, инициирует серию вызовов методов:

  • Он вызывает метод retrieveByCredentials класса App\Extensions\MongoUserProvider.
  • Метод retrieveByCredentials вызывает метод fetchUserByCredentials класса User App\Models\Auth\User.
  • Метод fetchUserByCredentials вызывает метод find из App\Database\MongoDatabase для получения учетных данных пользователя.
  • Наконец, метод find из App\Database\MongoDatabase возвращает ответ!

Если все работает так, как ожидалось, мы должны получить аутентифицированного пользователя, вызвав метод user нашего гуарда.

Чтобы получить доступ к контроллеру, вы должны добавить соответствующий маршрут в файле routes/web.php.

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

Попробуйте получить доступ к URL-адресу http://your-laravel-site/custom/mongo/login, не передавая никаких параметров, и вы должны увидеть сообщение «не авторизован».

С другой стороны, попробуйте что-то вроде http://your-laravel-site/custom/mongo/login?jsondata={"username":"admin", "password": "admin"}, и это должно вернуть сообщение об успешном завершении если пользователь присутствует в вашей базе данных.

Обратите внимание, что так сделано просто для примера, чтобы продемонстрировать, как работает пользовательский гуард. Вы должны реализовать надежное решение для такой функции, как логин. Фактически, я только что дал представление об потоке аутентификации; вы несете ответственность за создание надежного и безопасного решения для вашего приложения.

На этом наше путешествие сегодня заканчивается, и, надеюсь, что я вернусь с более полезными вещами. Если вы хотите, чтобы я писал на какие-либо конкретные темы, не забудьте оставить мне сообщение!

Заключение

Фреймворк Laravel обеспечивает надежную систему аутентификации, которая может быть расширена, если вы хотите реализовать свою кастомную. Это была тема сегодняшней статьи по внедрению пользовательского гуарда и подключению его к рабочему процессу аутентификации Laravel.

В ходе этого мы продолжили работу и разработали систему, которая аутентифицирует пользователя на основе JSON данных в запросе и сопоставляет его с базой данных MongoDB. И для этого мы создали кастомный гуард защиту и реализацию пользовательского провайдера.

Я надеюсь, что это упражнение предоставило вам понимание потока аутентификации Laravel, и теперь вы должны чувствовать себя в своих собственных действиях более уверенно.

Для тех из вас, кто только начинает работать с Laravel или хочет расширить свои знания, создать сайт или приложение с расширениями, у нас есть множество вещей, которые вы можете изучить на Envato Market.

Я хотел бы услышать ваши отзывы и предложения, поэтому кричите громко, используя приведенный ниже канал связи!

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.