Делаем авторизацию немного сложнее на Laravel 5.3

Иногда случается такое, что при авторизации необходимо проверить данные из реляционных таблиц, или добавить условие, которое фреймворком не предусмотрено.
Единственный для себя выход я нашел в создании своего драйвера для авторизации, начнем все по порядку:
- Для начала нужно создать свой Provider, который наследуется от EloquentUserProvider и переопределяем в нем метод retrieveByCredentials:
<?php namespace AppExtensions; use IlluminateSupportStr; use IlluminateAuthEloquentUserProvider; class CustomUserProvider extends EloquentUserProvider { /** * Retrieve a user by the given credentials. * * @param array $credentials * @return IlluminateContractsAuthAuthenticatable|null */ public function retrieveByCredentials(array $credentials) { if (empty($credentials)) { return; } // First we will add each credential element to the query as a where clause. // Then we can execute the query and, if we found a user, return it in a // Eloquent User "model" that will be utilized by the Guard instances. $query = $this->createModel()->newQuery(); foreach ($credentials as $key => $value) { if (!Str::contains($key, ['password', 'role'])) { $query->where($key, $value); } if (Str::contains($key, 'role')) { $query->whereHas('roles', function ($query) use ($value) { $query->where('slug', 'like', $value . '%'); }); } } return $query->first(); } }
- Теперь скажем фреймворку что работа с пользователями будет происходить через наш новый провайдер. Для этого изменим пару строк в config/auth.php:
'users' => [ 'driver' => 'custom', 'model' => AppEntitiesUser::class //Обратите внимание на путь к модели, у меня он не стандартный ],
- Но прежде чем проверять необходимо объявить провайдер. Для этого указываем в AuthServiceProvider в методе boot следующее:
Auth::provider('custom', function ($app, array $config) { return new CustomUserProvider($app['hash'], $config['model']); });
- Теперь можно проверить авторизацию, она будет работать через новый провайдер, но осталась ещё одна мелочь. Если посмотреть на код в пункте первом, видно что у меня в метод передаются данные с ключами role,password и стандартным полем email.
Чтобы добавить в массив $credentials данные необходимо в контроллере LoginController.php переопределить метод credentials, в моем случае это выглядело так:
/** * Get the needed authorization credentials from the request. * * @param IlluminateHttpRequest $request * @return array */ protected function credentials(Request $request) { $data = $request->only($this->username(), 'password'); $data['role'] = $this->accessRole; //приватная переменная, указывалась для каждого модуля отдельно return $data; }
Теперь авторизация готова и полностью работает. Вам необходимо будет только заменить выборку на свою в методе retrieveByCredentials в 1 пункте.