Как использовать аутентификацию токенов доступа
Дата обновления перевода 2023-01-12
Как использовать аутентификацию токенов доступа
Токены доступа или токены API часто используются как механизм аутентификации в контексте API. Токен доступа - это строка, получення во время аутентификации (используя приложение или сервер авторизации). Роль токена доступа заключается в верификации личности пользователя и получения согласия до выпуска токена.
Токены доступа могут быть любого вида, например, непрозрачными строками, веб-токенами JSON (JWT) или SAML2 (XML-структурами). Пожалуйста, прочтите RFC6750: Фреймворк авторизации OAuth 2.0: Использование токена предъявителя, чтобы узнать детали.
Использование аутентификатора токена доступа
Это руководство предполагает, что вы настроили безопасность и создали объект пользователя в вашем приложении. Следуйте основному руководству по безопасности, если это еще не так.
1) Сконфигурируйте аутентификатор токена доступа
Чтобы использовать аутентификатор токена доступа, вы должны сконфигурировать
token_handler
. Обработчик токенов получает токен из запроса и возврращает
правильный идентификатор пользователя. Чтобы получить идентификатор пользователя,
реализации может быть нужно загрузить и валидировать токен (например, аннулирование,
срок действия, цифровую подпись и т.д.).
- YAML
- XML
- PHP
1 2 3 4 5 6
# config/packages/security.yaml
security:
firewalls:
main:
access_token:
token_handler: App\Security\AccessTokenHandler
Этот обработчик должен реализовывать AccessTokenHandlerInterface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// src/Security/AccessTokenHandler.php
namespace App\Security;
use App\Repository\AccessTokenRepository;
use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
class AccessTokenHandler implements AccessTokenHandlerInterface
{
public function __construct(
private AccessTokenRepository $repository
) {
}
public function getUserBadgeFrom(string $accessToken): UserBadge
{
// например, запрос к базе данных "access token", чтобы искать этот токен
$accessToken = $this->repository->findOneByValue($token);
if (null === $accessToken || !$accessToken->isValid()) {
throw new BadCredentialsException('Invalid credentials.');
}
// и вернуть объект UserBadge, содержащий идентификатор пользователя из найденного токена
return new UserBadge($accessToken->getUserId());
}
}
Аутентификатор токена доступа будет использовать возвращенный идентификатор пользователя, чтобы загрузить пользователя, используя поставщика пользователей .
Caution
Важно проверить, валиден ли токен. Например, пример выше верифицирует, не
истек ли у токена срок действия. При использовании самодостаточных токенов
доступа, таких как JWT, обработчик должен верифицировать цифровую подпись
и понять все утверждения, особенно sub
, iat
, nbf
и exp
.
2) Сконфигурируйте экстрактор токенов (необязательно)
Теперь приложение готово к обработке входящих токенов. Экстрактор токенов извлекает токен из запроса (например, заголовка или тела запроса).
По умолчанию, токен доступа читается из параметра заголовка запроса Authorization
со схемой Bearer
(например, Authorization: Bearer the-token-value
).
Symfony предоставляет другие экстракторы, в соответствии с RFC6750:
header
(по умолчанию)-
Токен отправляется через заголовок запроса. Обычно -
Authorization
со схемойBearer
. query_string
-
Токен является частью строки запроса. Обычно -
access_token
. request_body
-
Токен является частью тела запроса во время запроса POST. Обычно -
access_token
.
Caution
Из-за уязвимости безопасности, связанной с методом URI, включая высокую
вероятность, что будет произведена запись лога URL или тела запроса, которые
содержат токен доступа, методы query_string
и request_body
НЕ ДОЛЖНЫ
быть использованы, кроме случаев, когда невозможно переместить токен доступа в
поле заголовка запроса.
Вы также можете создать пользовательский экстрактор. Класс должен реализовывать AccessTokenExtractorInterface.
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12
# config/packages/security.yaml
security:
firewalls:
main:
access_token:
token_handler: App\Security\AccessTokenHandler
# использовать другой встроенный экстрактор
token_extractors: request_body
# или предоставить ID сервиса пользовательского экстрактора
token_extractors: 'App\Security\CustomTokenExtractor'
Возможно установить несколько экстракторов. В таком случае, порядок имеет значение: первый в списке вызывается первым.
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9
# config/packages/security.yaml
security:
firewalls:
main:
access_token:
token_handler: App\Security\AccessTokenHandler
token_extractors:
- 'header'
- 'App\Security\CustomTokenExtractor'
3) Отправьте запрос
Это все! Ваше приложение теперь может аутентифицировать входящие запросы, используя токен API.
Используя экстрактор заголовка по умолчанию, вы можете протестировать функцию, отправив запрос таким образом:
1 2
$ curl -H 'Authorization: Bearer an-accepted-token-value' \
https://localhost:8000/api/some-route
Настройка обработчика успеха
По умолчанию, запрос продолжается (например, запускается контроллер для маршрута).
Если вы хотите настроить обработку успеха, создайте собственного обработчика успеха,
создав класс, реализующий
AuthenticationSuccessHandlerInterface,
и сконфигурируйте ID сервиса как success_handler
:
- YAML
- XML
- PHP
1 2 3 4 5 6 7
# config/packages/security.yaml
security:
firewalls:
main:
access_token:
token_handler: App\Security\AccessTokenHandler
success_handler: App\Security\Authentication\AuthenticationSuccessHandler
Tip
Если вы хотите настроить обработку неудачи по умолчанию, используйте опцию
failure_handler
и создайте класс, реализующий
AuthenticationFailureHandlerInterface.