How to use Access Token Authentication ¶
Access tokens or API tokens are commonly used as authentication mechanism in API contexts. The access token is a string, obtained during authentication (using the application or an authorization server). The access token's role is to verify the user identity and receive consent before the token is issued.
Access tokens can be of any kind, for instance opaque strings, JSON Web Tokens (JWT) or SAML2 (XML structures). Please refer to the RFC6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage for a detailed specification.
Using the Access Token Authenticator ¶
This guide assumes you have setup security and have created a user object in your application. Follow the main security guide if this is not yet the case.
1) Configure the Access Token Authenticator ¶
To use the access token authenticator, you must configure a token_handler
.
The token handler receives the token from the request and returns the
correct user identifier. To get the user identifier, implementations may
need to load and validate the token (e.g. revocation, expiration time,
digital signature, etc.).
-
YAML
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 |
# config/packages/security.yaml
security:
firewalls:
main:
access_token:
token_handler: App\Security\AccessTokenHandler
|
This handler must implement 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
{
// e.g. query the "access token" database to search for this token
$accessToken = $this->repository->findOneByValue($accessToken);
if (null === $accessToken || !$accessToken->isValid()) {
throw new BadCredentialsException('Invalid credentials.');
}
// and return a UserBadge object containing the user identifier from the found token
return new UserBadge($accessToken->getUserId());
}
}
|
The access token authenticator will use the returned user identifier to load the user using the user provider.
Caution
It is important to check the token if is valid. For instance, the
example above verifies whether the token has not expired. With
self-contained access tokens such as JWT, the handler is required to
verify the digital signature and understand all claims, especially
sub
, iat
, nbf
and exp
.
2) Configure the Token Extractor (Optional) ¶
The application is now ready to handle incoming tokens. A token extractor retrieves the token from the request (e.g. a header or request body).
By default, the access token is read from the request header parameter
Authorization
with the scheme Bearer
(e.g. Authorization: Bearer
the-token-value
).
Symfony provides other extractors as per the RFC6750:
header
(default)-
The token is sent through the request header. Usually
Authorization
with theBearer
scheme.トークンはリクエスト ヘッダーを介して送信されます。通常、Bearer 方式による Authorization。 query_string
-
The token is part of the request query string. Usually
access_token
.トークンは、リクエスト クエリ文字列の一部です。通常は access_token です。 request_body
-
The token is part of the request body during a POST request. Usually
access_token
.トークンは、POST 要求中の要求本文の一部です。通常はaccess_token。
Caution
Because of the security weaknesses associated with the URI method,
including the high likelihood that the URL or the request body
containing the access token will be logged, methods query_string
and request_body
SHOULD NOT be used unless it is impossible to
transport the access token in the request header field.
You can also create a custom extractor. The class must implement AccessTokenExtractorInterface.
-
YAML
YAML
-
XML
XML
-
PHP
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
# use a different built-in extractor
token_extractors: request_body
# or provide the service ID of a custom extractor
token_extractors: 'App\Security\CustomTokenExtractor'
|
It is possible to set multiple extractors. In this case, the order is important: the first in the list is called first.
-
YAML
YAML
-
XML
XML
-
PHP
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) Submit a Request ¶
That's it! Your application can now authenticate incoming requests using an API token.
Using the default header extractor, you can test the feature by submitting a request like this:
1 2 |
$ curl -H 'Authorization: Bearer an-accepted-token-value' \
https://localhost:8000/api/some-route
|
Customizing the Success Handler ¶
By default, the request continues (e.g. the controller for the route is
run). If you want to customize success handling, create your own success
handler by creating a class that implements
AuthenticationSuccessHandlerInterface
and configure the service ID as the success_handler
:
-
YAML
YAML
-
XML
XML
-
PHP
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
If you want to customize the default failure handling, use the
failure_handler
option and create a class that implements
AuthenticationFailureHandlerInterface.