Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sinbadxiii/phalcon-auth
Phalcon Auth - Authentication based guards and providers adapters
https://github.com/sinbadxiii/phalcon-auth
Last synced: 3 months ago
JSON representation
Phalcon Auth - Authentication based guards and providers adapters
- Host: GitHub
- URL: https://github.com/sinbadxiii/phalcon-auth
- Owner: sinbadxiii
- License: mit
- Created: 2021-03-11T09:40:14.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-03-21T03:49:17.000Z (over 1 year ago)
- Last Synced: 2024-07-25T01:54:55.718Z (4 months ago)
- Language: PHP
- Homepage:
- Size: 212 KB
- Stars: 8
- Watchers: 2
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-phalcon - Phalcon Auth - Out-of-the-box authentication component based on guards and providers. (Authentication & OAuth)
README
# Phalcon Auth
![Banner](https://github.com/sinbadxiii/images/blob/master/phalcon-auth/phalcon-auth-logo.png?raw=true)
You can see an example of an application with authentication here [sinbadxiii/phalcon-auth-example](https://github.com/sinbadxiii/phalcon-auth-example)
## Extended guards
* [JWT Guard](https://github.com/sinbadxiii/phalcon-auth-jwt)## Phalcon version
> Unfortunately version 2 of the library no longer supports Phalcon 4.
| Phalcon 3 | Phalcon 4 | Phalcon 5 | Phalcon 6
:-------------| :-------------| :-------------| :----------
| :x: | :x:| :heavy_check_mark: | :question:## PHP are supported
^7.4-8.1.
## Install
Require the project using composer:
`composer require "sinbadxiii/phalcon-auth:^v2.0.0"`
## Introduction
![Banner](https://github.com/sinbadxiii/images/blob/master/phalcon-auth/auth-scheme.webp?raw=true)
Phalcon Auth позволит вам создать систему аутентификации в вашем веб-приложении.
Система аутентификации имеет такие понятия как «Охранники» (Guard) и «Поставщики» (Provider), охранники определяют, как пользователи будут аутентифицироваться, например, используя стандартные Хранилища Сессии и файлов куки.
Провайдеры определяют, какие данные будут браться в качестве пользователей, и так же откуда будут извлекаться эти пользователи. Откуда будут извлекаться данные пользователей определяют Адаптеры (Adapter). Обычно это `Phalcon\Mvc\Model` и построитель запросов к базе данных.
Кроме того есть другие варианты адаптеров: файл или массив с данными. Можно создать свой адаптер, реализуя интерфейс адаптера. Об этом поговорим чуть позже.
> Guards и Providers не следует путать с «roles» и «permissions» [ACL](https://docs.phalcon.io/4.0/en/acl). Auth и ACL следует использовать вместе, если требуется более точная надстройка доступа к узлам приложения. Например использовать роль `manager` со специфическими правами.
## Быстрый старт
Полностью пример готового приложения с аутентификацией доступен по адресу [sinbadxiii/phalcon-auth-example](https://github.com/sinbadxiii/phalcon-auth-example). Это типовой проект на Phalcon, который можно использовать как старт нового приложения, либо же просто ознакомиться с возможностями аутентификации на примере данного приложения.
## Логика работы
Общий принцип работы аутентификации заключается в том, что пользователь вводит свое имя пользователя и пароль через форму входа. Если эти учетные данные верны, приложение сохранит информацию об аутентифицированном пользователе в сессии пользователя и будет считать пользователя "аутентифицированным". В случае использования "Запомнить меня" может быть создан файл cookie, который содержит идентификатор сессии, чтобы последующие запросы к приложению могли быть связаны с нужным пользователем. После получения идентификатора сессии из файла cookie приложение извлечет данные пользователя.
Возьмем другой случай, когда удаленному сервису необходимо пройти аутентификацию для доступа к API, обычно файлы cookie не используются для аутентификации, поскольку веб-браузер отсутствует. Вместо этого удаленная служба отправляет токен API при каждом запросе. Приложение может проверить входящий токен по таблице действительных токенов API и "аутентифицировать" запрос как выполненный пользователем, связанным с этим токеном API.
## Подготовка базы данных
Для использования данных из бд, понадобится создать таблицу `users`.Если необходимо будет использовать функцию "Запомнить меня" - `RememberMe`, которая позволяет хранить сеанс аутентификации пользователя длительное время, то так же понадобится таблица `users_remember_tokens`, ну и соответственно ее модель в виде `App\Models\RememberToken`.
Для быстрого создания таблиц вы можете импортировать файлы из папки `db/users.sql`, `db/users_remember_tokens.sql`, а так же `db/create_auth_token_users.sql`, если будете использовать в качестве Guard - Token, которому необходимо поле `auth_token` для корректной работы.
## Managers
При создании аутентификации вы можете воспользоваться одним из двух менеджеров: `Sinbadxiii\PhalconAuth\Manager` или `Sinbadxiii\PhalconAuth\ManagerFactory`.
## Manager
Если вы строго придерживаетесь философии фреймворка Phalcon и хотите вручную настроить все компоненты аутентификации, то вам понадобится класс `Sinbadxiii\PhalconAuth\Manager` - с помощью данного менеджера можно настроить охранника, адаптер поставщиков и распределить доступы пользователям.
```php
use Sinbadxiii\PhalconAuth\Manager;
use App\Models\User;
use Sinbadxiii\PhalconAuth\Adapter\Model;
use Sinbadxiii\PhalconAuth\Guard\Session;$auth = new Manager();
$configAdapter = [
'model' => User::class,
];$adapter = new Model($this->getSecurity(), $configAdapter);
$guard = new Session(
$adapter,
$this->getSession(),
$this->getCookies(),
$this->getRequest(),
$this->getEventsManager()
);$auth->addGuard("web", $guard, true);
return $auth;
```В результате получился менеджер, который будет искать пользователей через модель `User` в таблице базе данных `users`.
Результат аутентификации будет храниться в сессии, и куках, если выбрать "Запомнить меня".
В качестве других аргументов нужно передать сервис провайдеры `$this->security`, `$this->session`, `$this->cookies`, `$this->request`, `$this->eventsManager`, которые будут необходимы при дальнейшем использовании охранника и адаптера поставщиков.- public addGuard(string $nameGuard, GuardInterface $guard, bool $isDefault = false) - добавить охранника
- public guard(?string $name = null) - получить конкретного охранника или по заданного по дефолту
- public setDefaultGuard(GuardInterface $guard) - задать охранника по дефолту
- public getDefaultGuard() - получить охранника по дефолту
- public access(string $accessName) - назначить контроллеру определенный доступ
- public getAccess(string $accessName) - назначить требуемый доступ
- public setAccess(AccessInterface $access) - получить требуемый доступ
- public setAccessList(array $accessList) - зарегистрировать список доступов
- public addAccessList(array $accessList) - добавить список доступов
- public except(...$actions) - исключенные экшны из проверки доступа
- public only(...$actions) - обязательные экшны для проверки доступа
- public __call() - magic __call## Guards
На данный момент существует два вида Охранников, которые покроют 90% типовых задач создания аутентификации веб-приложений.
Это `Sinbadxiii\PhalconAuth\Guard\Session` и `Sinbadxiii\PhalconAuth\Guard\Token`, указывая одного из этих охранников вы выбираете, что будете использовать в своем приложении, аутентификацию на основе сессий или токена.Предположительно Сессии вы будете использовать в веб-приложениях после логина в личный кабинет,а Токен, например, в микро приложениях в качестве api сервисов. Но ничего вам не мешает применять или комбинировать охранников в нестандартных приложениях.
## Session Guard
```php
use Sinbadxiii\PhalconAuth\Manager;
use App\Models\User;
use Sinbadxiii\PhalconAuth\Adapter\Model;
use Sinbadxiii\PhalconAuth\Guard\Session;$auth = new Manager();
$configAdapter = [
'model' => User::class,
];$adapter = new Model($this->getSecurity(), $configAdapter);
$guard = new Session(
$adapter,
$this->getSession(),
$this->getCookies(),
$this->getRequest(),
$this->getEventsManager()
);$auth->addGuard("web", $guard, true);
return $auth;
```- public function __construct(AdapterInterface $adapter, SessionManagerInterface $session,
Cookies $cookies, Request $request, EventsManagerInterface $eventsManager)
- public function attempt(array $credentials = [], $remember = false) - попытка аутентификации
- public function user() - получить аутентифицированного пользователя
- public function validate(array $credentials = []) - валидация входных данных
- public function getName() - получение имени сессии
- public function getRememberName() - имя куки при запомнить меня
- public function login(AuthenticatableInterface $user, bool $remember = false) - логин экземпляра пользователя
- public function loginById($id, bool $remember = false) - логин по Id пользователя
- public function once(array $credentials = []) - логин без сохранения пользователя в сессию
- public function logout() - выход
- public function getLastUserAttempted() - получение последнего попытавшегося залогиниться пользователя
- public function viaRemember() - проверка что пользователь был вытащен из Запомнить меня
- public function getUser() - получить пользователя
- public function setRequest(Request $request)
- public function setSession(SessionManagerInterface $session)
- public function setCookies(Cookies $cookies)
- public function getAdapter() - получить адаптер поставщика
- public function setAdapter(AdapterInterface $adapter) - назначить адаптера поставшикаBasic
- public function basic(string $field = 'email', array $extraConditions = []) - аутентификация через Basic Auth
- public function onceBasic(string $field = 'email', array $extraConditions = []) - аутентификация через Basic Auth без сохранения в сессию## Token Guard
Чтобы воспользоваться `Sinbadxiii\PhalconAuth\Guard\Token`, необходимо в качестве второго аргумента передать конфиг с названиями имя параметра запроса и поля в хранилище данных пользователей, например, поле таблицы `users` в бд:
```php
[
...
'inputKey' => 'auth_token', //имя параметра с токеном
'storageKey' => 'auth_token', //имя поля в хранилище пользователей
...
]
```
```php
use Sinbadxiii\PhalconAuth\Manager;
use App\Models\User;
use Sinbadxiii\PhalconAuth\Adapter\Model;
use Sinbadxiii\PhalconAuth\Guard\Token;$auth = new Manager();
$configAdapter = [
'model' => User::class,
];$configGuard = [
'inputKey' => 'auth_token',
'storageKey' => 'auth_token',
];$adapter = new Model($this->getSecurity(), $configAdapter);
$guard = new Token(
$adapter,
$configGuard
$this->getRequest()
);$auth->addGuard("api", $guard, true);
return $auth;
```
Соответствено GET запрос должен будет иметь вид:```shell
//GET
https://yourapidomain/api/v2/users?auth_token=fGaYgdGPSfEgT41r3F4fg33
```
POST запрос:
```shell
//POST
//params POST request
[
"auth_token": "fGaYgdGPSfEgT41r3F4fg33"
]https://yourapidomain/api/v2/users
```
или заголовок `Authorization`:```shell
Authorization: Bearer fGaYgdGPSfEgT41r3F4fg33https://yourapidomain/api/v2/users
```> Помните, что каждый ваш запрос к приложению, должен сопровождаться параметром `auth_token` с токеном доступа.
- public function __construct(AdapterInterface $adapter, array $config, Request $request)
- public function user() - аутентифицированный пользователь
- public function validate(array $credentials = []) - валидация
- public function getTokenForRequest() - поулчить токен из запросов (GET, POST, Headers)
- public function setRequest(Request $request)
- public function getRequest()
- public function getAdapter()
- public function setAdapter(AdapterInterface $adapter)## Создание своего Охранника
```php
auth->access("auth");
}public function indexAction()
{
}
}
```
В то время как к контроллеру регистрации, например, нужен доступ только неаутентифицированным пользователям - гостям:```php
auth->access("guest");
}public function indexAction()
{
}
}
```
Задается доступ в конструкторе контроллера `onConstruct()`.Из коробки есть два основных вида доступа - аутентифицированный и гостевой:
- `Sinbadxiii\PhalconAuth\Access\Auth`
- `Sinbadxiii\PhalconAuth\Access\Guest`Если доступ удовлетворяет условию в методе `allowIf`, то дается разрешение на дальнейшее использование контроллера, например в дефолтном `auth` условием является:
```php
class Auth extends AbstractAccess
{
/**
* @return bool
*/
public function allowedIf(): bool
{
if ($this->auth->check()) {
return true;
}return false;
}
}
````$this->auth->check()` - проверка на аутентификацию пользователя, т.е. чтобы получить доступ к `$this->auth->access('auth')` нужно быть аутентифицированным, а вот условие у `$this->auth->access('guest')` прямо противоположно:
```php
auth->guest()) {
return true;
}return false;
}
}
```
В случае если метод `allowedIf()` вернет `true`, то пользователь сможет идти дальше, если же результат будет равен `false`, то сработает метод неудачи `redirectTo()`, и приложение перенаправит пользователя, т.к. у каждого приложение логика перенаправлений может быть разная, то вам следует создать свои классы Access `auth` и `guest`, наследовав от дефолтных классов и переопределить метод `redirectTo()`:
```php
response)) {
return $this->response->redirect("/login")->send();
}
}
}
```
и
```php
response)) {
return $this->response->redirect("/profile")->send();
}
}
}
```
Чтобы создать свой Access, можно имплементировать интерфейс `Sinbadxiii\PhalconAuth\Access\AccessInterface`:```php
auth->user() and $user->getRole() === "admin") {
return true;
}return false;
}/**
* @return void
* @throws Exception
*/
public function redirectTo()
{
if (isset($this->response)) {
return $this->response->redirect("/admin-login")->send();
}
}
}
```
или пример проверки доступа для Http Basic Auth:```php
auth->basic("email")) {
return true;
}return false;
}/**
* @return void
* @throws Exception
*/
public function redirectTo()
{
throw new Exception("Basic: Invalid credentials.");
}
}
```## Регистрация доступов
Доступы должны быть зарегистрированы в системе аутентификации, если этого не сделать, то при запросе доступа `$this->auth->access("auth")` будет выдаваться ошибка, типа:
`Access with 'auth' name is not included in the access list`.Чтобы зарегистрировать доступы в системе, необходимо создать некоторое промежуточное программное обеспечение, подтипа middleware и прикрепить его к `dispatcher` приложения.
Минимальный вид класса `App\Security\Authenticate` будет таков:
```php
Auth::class,
'guest' => Guest::class
];
}
```А затем необходимо прикрепить его к сервиc-провайдеру `dispatcher`:
```php
$di->setShared('dispatcher', function () use ($di) {$dispatcher = new Phalcon\Mvc\Dispatcher();
$eventsManager = $di->getShared('eventsManager');
$eventsManager->attach('dispatch', new App\Security\Authenticate());
$dispatcher->setEventsManager($eventsManager);return $dispatcher;
});
```
Свойство `$accessList` позволяет быстро добавлять новые уровни доступа в приложении, например, чтобы добавить новый доступ `admin`, достаточно создать класс с условием и добавить его в список `$accessList`:
```php
Auth::class,
'guest' => Guest::class,
'admin' => Admin::class,
];
}
```
Так же список доступов можно зарегистрировать непосредственно в Manager при создании сервис провайдера с помощью метода `setAccessList()`:
```php$authManager = new Sinbadxiii\PhalconAuth\Manager();
$authManager->setAccessList(
[
'auth' => App\Security\Access\Auth::class,
'guest' => App\Security\Access\Guest::class,
'admin' => App\Security\Access\Admin::class,
];
);
return $authManager;
```## Поставщики (Providers) и Адаптеры (Adapters)
Как уже было сказано ранее поставщики определяют какие сущности будут являться пользователями, например `users` или `contacts`, все зависит от контекста вашего приложения.
В настоящий момент существуют три вида адаптера:
- `Sinbadxiii\PhalconAuth\Adapter\Model`
- `Sinbadxiii\PhalconAuth\Adapter\Stream`
- `Sinbadxiii\PhalconAuth\Adapter\Memory`Модель, файл и массив с данными в приложении.
Все адаптеры наследуются от абстрактного класса `Sinbadxiii\PhalconAuth\Adapter\AbstractAdapter`, который имеет:- public setModel(AuthenticatableInterface $model)` - назначить модель поставщика
- public getModel()` - получить модель поставщика
- public setConfig(array $config)` - установить конфиг
- public getConfig()` - получить конфиг адаптера## Адаптер поставщика `Model`
Для использования адаптера `Model` нам понадобится модель пользователя, например `App\Models\User::class` вида:
```php
setSource("users");
}
}
```Чтобы при использовании в нашем приложении, не выдавалась ошибка:
`PHP Fatal error: Uncaught TypeError: Sinbadxiii\PhalconAuth\Adapter\Model::validateCredentials(): Argument #1 ($user) must be of type Sinbadxiii\PhalconAuth\AuthenticatableInterface`.
Т.е. модель `User` надо имплементировать от `Sinbadxiii\PhalconAuth\AuthenticatableInterface`, а если хочется использовать возможности функции `RememberMe` (Запомнить меня), то так же надо будет наследовать интерфейс `Sinbadxiii\PhalconAuth\RememberingInterface`:
В конечном счете, ваша модель должна иметь класс следующего вида:```php
setSource("users");$this->hasOne(
'id',
RememberToken::class,
'user_id',
[
'alias' => "remember_token"
]
);
}public function setPassword(string $password)
{
$this->password = $this->getDI()->get("security")->hash($password);
return $this;
}public function getAuthIdentifier()
{
return $this->id;
}public function getAuthPassword()
{
return $this->password;
}public function getRememberToken(string $token = null): ?RememberTokenInterface
{
return $this->getRelated('remember_token', [
'token=:token:',
'bind' => ['token' => $token]
]);
}public function setRememberToken(RememberTokenInterface $value)
{
$this->remember_token = $value;
}public function createRememberToken(): RememberTokenInterface
{
$random = new Random();$token = $random->base64(60);
$rememberToken = new RememberToken();
$rememberToken->token = $token;
$rememberToken->user_agent = $this->getDI()->get("request")->getUserAgent();
$rememberToken->ip = $this->getDI()->get("request")->getClientAddress();$this->setRememberToken($rememberToken);
$this->save();return $rememberToken;
}
}
```Модель `App\Models\RememberToken` будет иметь вид:
```php
setSource("users_remember_tokens");
}public function getToken(): string
{
return $this->token;
}public function getUserAgent(): string
{
return $this->user_agent;
}
public function beforeValidationOnCreate()
{
$this->created_at = date(DATE_ATOM);
$this->updated_at = date(DATE_ATOM);
if (!$this->expired_at) {
$this->expired_at = date(DATE_ATOM);
}
}public function beforeValidationOnSave()
{
if (!$this->created_at) {
$this->created_at = date(DATE_ATOM);
}
if (!$this->expired_at) {
$this->expired_at = date(DATE_ATOM);
}
$this->updated_at = date(DATE_ATOM);
}public function beforeValidationOnUpdate()
{
$this->updated_at = date(DATE_ATOM);
}
}
```
Интерфейс `Sinbadxiii\PhalconAuth\AuthenticatableInterface` имеет следущий вид:```php
getSecurity();$adapter = new Model($security);
$adapter->setModel(App\Models\User::class);
$guard = new Session(
$adapter,
$this->getSession(),
$this->getCookies(),
$this->getRequest(),
$this->getEventsManager()
);$manager = new Manager();
$manager->addGuard("web", $guard);
$manager->setDefaultGuard($guard);return $manager;
```## Адаптер поставщика `memory`
Используя `setData()` можно задать массив данных с пользователями, который имеет вид:
```php
[
["username" =>"admin", "name" => "admin", 'password' => 'admin', "email" => "[email protected]"],
["username" => "user", "name" => "user", 'password' => 'user', "email" => "[email protected]"],
]
``````php
$di->setShared("auth", function () {$security = $this->getSecurity();
$data = [
["auth_token" => '1', "name" => "admin", "username" => "admin", 'password' => 'admin', "email" => "[email protected]"],
["auth_token" => '2', "name" => "admin1", "username" => "admin", 'password' => 'admin1', "email" => "[email protected]"],
];$adapter = new \Sinbadxiii\PhalconAuth\Adapter\Memory($security);
$adapter->setModel(App\Models\UserSimple::class);
$adapter->setData($data);
$configGuard = [
'inputKey' => 'auth_token',
'storageKey' => 'auth_token',
];$guard = new \Sinbadxiii\PhalconAuth\Guard\Token(
$adapter,
$configGuard,
$this->getRequest()
);
$manager = new Manager();
$manager->addGuard("api", $guard, true);return $manager;
});
```- public setData(array $data) - массив с данными
- public getData() - получить массив с данными## Адаптер поставщика `Stream`
Если взять в качестве адаптера поставщиков `users` не `Sinbadxiii\PhalconAuth\Adapter\Model`, а файл `Sinbadxiii\PhalconAuth\Adapter\Stream`:
то необходимо будет задать источник файла формата `json`, например, `users.json`, который имеет вид:```json
[
{"name":"admin", "username":"admin", "password": "admin","email": "[email protected]"},
{"name":"user", "username":"user", "password": "user","email": "[email protected]"}
]
```Возвращаемый пользователь в виде модели `App\Models\UserSimple` должен будет реализовывать интерфейс `Sinbadxiii\PhalconAuth\AuthenticatableInterface`, например:
```php
$value) {
$this->$field = $value;
}
}/**
* @return int
*/
public function getAuthIdentifier(): mixed
{
return $this->id;
}/**
* @return string
*/
public function getAuthPassword(): string
{
return $this->password;
}
}```
но следует учитывать, что нельзя будет использовать функцию `RememberMe` (Запомнить меня), т.к. `Stream`
не имплементирует интерфейс `Sinbadxiii\PhalconAuth\RememberingInterface` ввиду отсутствия возможности сохранить токен сессии в файлом хранилище пользователей (что не мешает вам реализовать эту функцию в своем охраннике на основе хранилища в файле).```php
$security = $this->getSecurity();$adapter = new \Sinbadxiii\PhalconAuth\Adapter\Stream($security);
$adapter->setModel(App\Models\UserSimple::class);
$adapter->setFileSource(__DIR__ . "/users.json");$guard = new \Sinbadxiii\PhalconAuth\Guard\Session(
$adapter,
$this->getSession(),
$this->getCookies(),
$this->getRequest(),
$this->getEventsManager()
);$manager = new Manager();
$manager->addGuard("web", $guard, true); //третий аргумент - назначить охранника по дефолтуreturn $manager;
```- public setFileSource(string $pathSrcFile) - указать путь к файлу
- public getFileSource() - получить путь к файлу
- public setData(array $data) - массив с данными пользователей
- public getData() - получить массив с данными пользователей> Не рекомендуется использовать адаптеры `stream` и `memory` в реальных приложениях из-за их функциональной ограниченности и сложности управления пользователями. Это может быть полезно в прототипах приложений и для ограниченных приложений, которые не хранят пользователей в базах данных.
## Создание своего адаптера поставщика
Интерфейс адаптера поставщика `Sinbadxiii\PhalconAuth\Adapter\AdapterInterface` имеет вид:
```php
setShared('auth', function () {
$manager = new \Sinbadxiii\PhalconAuth\ManagerFactory();
return $manager;
});
```Все, дальше `ManagerFactory` сделает все за вас, на основе вашего конфигурационного файла. По умолчанию используется конфигурация из `$this->config->auth`, если вы хотите использовать другую конфигурацию, отличную от `$this->config->auth` то можно передать в качестве первого аргумента другой конфиг:
```php
$di->setShared("auth", function () {
$config = $this->getConfig()->auth_config_other;$manager = new \Sinbadxiii\PhalconAuth\ManagerFactory($config->toArray());
return $manager;
});
```
### Пример конфигурационного файла для использования СессийИтак, типичный пример конфигурационного файла приложения на основе Сессий. Файл может находится в папке конфигов `config/auth.php` или в глобальном файле `config.php` с доступом по ключу `auth` (`$this->config->auth`).
```php
[
'defaults' => [ //дефолтные значения
'guard' => 'web' //дефолтный охранник
],
'guards' => [ //список охранников
'web' => [
'driver' => 'session', //драйвер сессия
'provider' => 'users', //поставщики users
],
],
'providers' => [
'users' => [
'adapter' => 'model', //адаптер поставщика users - model
'model' => App\Models\User::class, //модель
]
]
],
];
```Т.е. приложение будет использовать `guard = web`. В свою очередь Охранник web основан на драйвере `session` и использует поставщика пользователей `users`, которые извлекаются через Адаптера `model` - `App\Models\Users`.
Данный конфигурационный файл позволяет создавать различные комбинации охранников и поставщиков, разделяя доступы в вашем приложений.### Пример конфигурационного файла для использования Токена
```php
[
'defaults' => [
'guard' => 'api'
],
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'inputKey' => 'auth_token', //опционально, по дефолту auth_token
'storageKey' => 'auth_token', //опционально, по дефолту auth_token
],
],
'providers' => [
'users' => [
'adapter' => 'model',
'model' => App\Models\User::class,
]
]
],
];
```Расширить охранников можно с помощью `extendGuard` и передать в качестве аргумента имя охранника, используемого в конфиге `jwt`, а так же `Closure` с передачей аргументов в новый класс охранника, например:
```php
$di->setShared('auth', function () {
$auth = new \Sinbadxiii\PhalconAuth\ManagerFactory();
$request = $this->getRequest();$manager->extendGuard("jwt", function ($adapter, $config) use ($request) {
return new JwtGuard($adapter, $config, $request);
});
return $auth;
});
```Вы можете расширить список адаптеров с помощью метода `extendProviderAdapter`, например:
```php
$di->setShared("auth", function () {
$authManager = new Phalcon\Auth\ManagerFactory();$authManager->extendProviderAdapter("mongo", function($security, $configProvider) {
return new App\Security\Adapter\Mongo($security, $configProvider);
});return $authManager;
});
```## Методы
### Задать требуемый доступ к контроллеру
Метод `access()` позволит задать требуемый доступ к контроллеру, из коробки `auth` - для аутентифицированных, `guest` - для гостей.
```php
$this->auth->access("auth")
```
```php
auth->access("auth");
}public function indexAction()
{
}
}
```### Проверка аутентификации текущего пользователя
Чтобы определить, аутентифицирован ли пользователь, выполняющий входящий HTTP-запрос, вы можете использовать метод `check()`. Этот метод вернет true, если пользователь аутентифицирован:
```php
$this->auth->check();
//check authentication
```
Например, вы можете проверить на странице формы входа, что если пользователь вошел в систему, то не показывать ему форму ввода:```php
public function loginFormAction()
{
if ($this->auth->check()) {
//redirect to profile page
return $this->response->redirect(
"/profile", true
);
}
}
```### Получение аутентифицированного пользователя
При обработке входящего запроса вы можете получить доступ к аутентифицированному пользователю с помощью метода `user()`. Результатом будет провайдер, указанный в конфигурации `config->auth`, в соответствии с интерфейсом `Sinbadxiii\PhalconAuth\AuthenticatableInterface`.
Вы также можете запросить идентификатор пользователя (ID) с помощью метода `id()`:
```php
$this->auth->user(); //get the user$this->auth->id(); //get user id
```### Попытка аутентификации
Метод `attempt()` используется для обработки попыток аутентификации из формы входа в ваше приложение:
```php
$username = $this->request->getPost("username");
$password = $this->request->getPost("password");//attempt login with credentials
if ($this->auth->attempt(['username' => $username, 'password' => $password])) {//success attempt
...
}//fail attempt
```Метод `attempt()` принимает в качестве первого аргумента массив пар ключ/значение. Значения в массиве будут использоваться для поиска пользователя в таблице базы данных пользователей. Итак, в приведенном выше примере пользователь будет получен по значению столбца имени пользователя. Если пользователь найден, хешированный пароль, хранящийся в базе данных, будет сравниваться со значением пароля, переданным методу. Вы не должны хешировать значение входящего запроса пароля, так как пароль уже автоматически хэшируется, чтобы сравнить его с хешированным паролем в базе данных. Аутентифицированный сеанс будет запущен для пользователя, если хешированные пароли совпадают.
Помните, что пользователи из вашей базы данных будут запрашиваться на основе конфигурации «поставщика».
Метод `attempt()` вернет `true`, если аутентификация прошла успешно. В противном случае будет возвращено `false`.
### Указание дополнительных учетных данных
Вы также можете добавить запрос дополнительных данные в дополнение к электронной почте/имени пользователя и паролю. Для этого просто добавьте условия запроса в массив, переданный методу `attempt()`. Например, мы можем проверить, является ли пользователь опубликованным `is_published`:
```php
$username = $this->request->getPost("username");
$password = $this->request->getPost("password");//attempt login with additional credentials
if ($this->auth->attempt(['username' => $username, 'password' => $password, 'is_published' => 1])) {//success attempt
...
}//fail attempt
```### "Запомнить меня"
Если вы хотите обеспечить функциональность «запомнить меня» в своем приложении, вы можете передать логическое значение в качестве второго аргумента метода попытки.
Если это значение равно `true`, пользователь будет аутентифицироваться на неопределенный срок или до тех пор, пока пользователь не выйдет из системы вручную с помощью `logout()`. Таблица `users_remember_tokens` содержит столбец строки токена, который будет использоваться для хранения токена «запомнить меня»:
```php
$username = $this->request->getPost("username");
$password = $this->request->getPost("password");
$remember = this->request->getPost('remember') ? true : false;//attempt login with credentials and remember
if ($this->auth->attempt(['username' => $username, 'password' => $password], $remember)) {//success attempt
...
}//fail attempt
```
Используйте метод `viaRemember()`, чтобы проверить, аутентифицирован ли пользователь с помощью файла cookie «запомнить меня»:
```php
//use method viaRemember to check the user was authenticated using the remember me cookie
$this->auth->viaRemember();
```### Аутентифицировать пользовательский экземпляр
Если вам нужно установить существующий пользовательский экземпляр в качестве текущего аутентифицированного пользователя, вы можете передать пользовательский экземпляр методу `login()`. Данный пользовательский экземпляр должен быть реализацией `Sinbadxiii\PhalconAuth\AuthenticatableInterface`.
Этот метод аутентификации полезен, когда у вас уже есть действующий экземпляр пользователя, например, сразу после регистрации пользователя в вашем приложении:
```php
$user = Users::findFirst(1);
// Login and Remember the given user
$this->auth->login($user, $remember = true);
```### Аутентифицировать пользователя по идентификатору
Для аутентификации пользователя с использованием первичного ключа записи в базе данных вы можете использовать метод `loginById()`. Этот метод принимает первичный ключ пользователя, которого вы хотите аутентифицировать:
```php
//and force login user by id
$this->auth->loginById(1, true);
```### Аутентифицировать пользователя один раз
Используя метод `once()` вы можете аутентифицировать пользователя в приложении для одного запроса. При вызове этого метода не будут использоваться сессии или файлы cookie:
```php
//once auth without saving session and cookies
$username = $this->request->getPost("username");
$password = $this->request->getPost("password");
$this->auth->once(['username' => $username, 'password' => $password]);
```## Выход
Чтобы вручную разлогинить пользователя из вашего приложения, вы можете использовать метод `logout()`. После этого удалится вся информация об аутентификации из сессии пользователя, так что последующие запросы уже не будут аутентифицированы.
```php
$this->auth->logout();
//log out user
```## HTTP Basic Authentication
[Базовая аутентификация HTTP](https://en.wikipedia.org/wiki/Basic_access_authentication) обеспечивает быстрый способ аутентификации пользователей вашего приложения без настройки специальной страницы «входа в систему». Достаточно передать в заголовке `Authorization`, значение `Basic` и пары емейл (либо другое поле пользователя) и пароль, разделенные двоеточием и закодированые `base64_encode()`
Метод `$this->auth->basic("email")` позволит создать свой Access для использования доступа с помощью Auth Basic.
Аргумент `email` указывает на то, что поиск пользователя будет осуществляться по полям email и password. Указав другое поле, например `username`, поиск будет осуществляться по паре `username` и `password`:
```php
auth->basic("email")) {
return true;
}return false;
}/**
* @return void
* @throws Exception
*/
public function redirectTo()
{
throw new Exception("Basic: Invalid credentials.");
}
}
```
После запроса, в сессию запишется пользователь, и последующие запросы, могут уже не содержать пользовательские данные в заголовке `Authorization`, до тех пор пока сессия не "стухнет".### Basic HTTP-аутентификация без сохранения состояния
Вы можете использовать базовую аутентификацию HTTP без сохранения пользователя в сессии. Это в первую очередь полезно, если вы решите использовать HTTP-аутентификацию для аутентификации запросов к API вашего приложения. Для этого можно создать Access, который вызывает метод `onceBasic()`, например:
```php
auth->onceBasic("email")) {
return true;
}return false;
}/**
* @return void
* @throws Exception
*/
public function redirectTo()
{
throw new Exception("Basic: Invalid credentials.");
}
}
```После запроса, ни куки, ни сессия не будут содержать данные о пользователе, и следущий запрос так же должен содержать пользовательские данные заголовка `Authorization`, иначе будет вызвано исключение `Sinbadxiii\PhalconAuth\Exceptions`
## Events
| Event Name | Can stop operation? |
|--------------|-----------------|
| beforeLogin | Yes |
| afterLogin | No |
| beforeLogout | Yes |
| afterLogout | No |### License
The MIT License (MIT). Please see [License File](https://github.com/sinbadxiii/phalcon-auth/blob/master/LICENSE) for more information.