### Install Project Dependencies with Composer Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/CONTRIBUTING.md Set up the project by installing all necessary dependencies using Composer. ```bash $ composer install ``` -------------------------------- ### Install Lexik JWT Authentication Bundle Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Use Composer to add the bundle to your project. This command installs the bundle and its dependencies. ```bash $ php composer.phar require "lexik/jwt-authentication-bundle" ``` -------------------------------- ### Install Web-Token Bundle Dependency Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Install the necessary dependency to enable the Web-Token feature. This command should be run in your project's root directory. ```sh composer require web-token/jwt-bundle ``` -------------------------------- ### Configure Cookie Options Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst This example shows the full configuration for cookie options, including lifetime, samesite attribute, path, domain, secure, httpOnly, and partitioned settings. ```yaml # BEARER: # lifetime: null (defaults to token ttl) # samesite: lax # path: / # domain: null (null means automatically set by symfony) # secure: true (default to true) # httpOnly: true # partitioned: false ``` -------------------------------- ### After: Security and Bundle Configuration (2.0) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/UPGRADE-2.0.md This YAML configuration demonstrates the updated security setup using Guard authenticators and the new bundle configuration for token extractors in version 2.0. ```yaml # app/config/security.yml firewalls: api: guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator # app/config/config.yml lexik_jwt_authentication: # ... token_extractors: authorization_header: ~ cookie: ~ query_parameter: ~ ``` -------------------------------- ### Before: Security Configuration (1.x) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/UPGRADE-2.0.md This YAML configuration shows the security setup for JWT authentication in version 1.x, including deprecated options. ```yaml # app/config/security.yml firewalls: api: lexik_jwt: authorization_header: ~ cookie: ~ query_parameter: ~ throw_exceptions: false create_entry_point: true authentication_provider: lexik_jwt_authentication.security.authentication.provider authentication_listener: lexik_jwt_authentication.security.authentication.listener ``` -------------------------------- ### Enable Cookie Token Extractor Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Configure the bundle to extract JWT tokens from cookies. This example enables the cookie extractor and specifies the cookie name. ```yaml token_extractors: cookie: enabled: true name: BEARER # ... set_cookies: BEARER: ~ ``` -------------------------------- ### Example JWT Token Response Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst A successful login request returns a JSON object containing the JWT token. This token should be used in subsequent requests to authenticate the user. ```json { "token" : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE0MzQ3Mjc1MzYsInVzZXJuYW1lIjoia29ybGVvbiIsImlhdCI6IjE0MzQ2NDExMzYifQ.nh0L_wuJy6ZKIQWh6OrW5hdLkviTs1_bau2GqYdDCB0Yqy_RplkFghsuqMpsFls8zKEErdX5TYCOR7muX0aQvQxGQ4mpBkvMDhJ4-pE4ct2obeMTr_s4X8nC00rBYPofrOONUOR4utbzvbd4d2xT_tj4TdR_0tsr91Y7VskCRFnoXAnNT-qQb7ci7HIBTbutb9zVStOFejrb4aLbr7Fl4byeIEYgp2Gd7gY" } ``` -------------------------------- ### Create a Custom JWT Authenticator Class Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/6-extending-jwt-authenticator.rst Extend the JWTAuthenticator class to implement your own authentication logic. This is the starting point for customizing JWT authentication. ```php namespace App\Security; use Lexik\Bundle\JWTAuthenticationBundle\Security\Authenticator\JWTAuthenticator; class CustomAuthenticator extends JWTAuthenticator { // Your own logic } ``` -------------------------------- ### Custom JWT Encoder Implementation Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/5-encoder-service.rst Implement the JWTEncoderInterface to create a custom JWT encoder. This example uses the nixilla/php-jwt library. Ensure the key used for encoding and decoding is consistent. ```php namespace App\Encoder; use JWT\Authentication\JWT; use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface; use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTEncodeFailureException; use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException; /** * NixillaJWTEncoder * * @author Nicolas Cabot */ class NixillaJWTEncoder implements JWTEncoderInterface { private $key; public function __construct(string $key = 'super_secret_key') { $this->key = $key; } /** * {@inheritdoc} */ public function encode(array $data) { try { return JWT::encode($data, $this->key); } catch (\Exception $e) { throw new JWTEncodeFailureException(JWTEncodeFailureException::INVALID_CONFIG, 'An error occurred while trying to encode the JWT token.', $e); } } /** * {@inheritdoc} */ public function decode($token) { try { return (array) JWT::decode($token, $this->key); } catch (\Exception $e) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid JWT Token', $e); } } } ``` -------------------------------- ### JWT Cookie Configuration Example Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Defines JWT cookies with specific attributes like lifetime, samesite policy, and HTTP-only status. The 'partitioned' option is available for Symfony 6.4+. ```yaml enabled: true cookies: - jwt_hp - jwt_s set_cookies: jwt_hp: lifetime: null samesite: strict path: / domain: null httpOnly: false partitioned: false # Only for Symfony 6.4 or higher split: - header - payload jwt_s: lifetime: 0 samesite: strict path: / domain: null httpOnly: true partitioned: false # Only for Symfony 6.4 or higher split: - signature ``` -------------------------------- ### Customizing JWT Authentication Failure Response Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst This example shows how to set a custom data payload and message for a JWT authentication failure response. ```php use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse; use Symfony\Component\HttpFoundation\JsonResponse; /** * @param AuthenticationFailureEvent $event */ public function onAuthenticationFailureResponse(AuthenticationFailureEvent $event) { $data = [ 'name' => 'John Doe', 'foo' => 'bar', ]; $response = new JWTAuthenticationFailureResponse('Bad credentials, please verify that your username/password are correctly set', JsonResponse::HTTP_UNAUTHORIZED); $response->setData($data); $event->setResponse($response); } ``` -------------------------------- ### Configure CORS for API Paths Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/4-cors-requests.rst This YAML snippet shows how to configure CORS rules for API paths using NelmioCorsBundle. It specifies allowed origins, headers, methods, and max age for requests starting with '/api/'. Ensure your firewall paths are configured to allow CORS. ```yaml nelmio_cors: ... paths: '^/api/': allow_origin: ['*'] allow_headers: ['*'] allow_methods: ['POST', 'PUT', 'GET', 'DELETE'] max_age: 3600 ``` -------------------------------- ### Migrate Configuration to Web-Token Format Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Use this console command to automatically migrate your existing configuration to the Web-Token format. This is recommended for development environments. ```sh bin/console lexik:jwt:migrate-config ``` -------------------------------- ### Minimal Configuration with RSA/ECDSA Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Configure the bundle with paths to your RSA/ECDSA private and public keys, along with a passphrase for token creation. Additional public keys can be specified for token verification. ```yaml # config/packages/lexik_jwt_authentication.yaml #... lexik_jwt_authentication: secret_key: '%kernel.project_dir%/config/jwt/private.pem' # path to the secret key OR raw secret key, required for creating tokens public_key: '%kernel.project_dir%/config/jwt/public.pem' # path to the public key OR raw public key, required for verifying tokens pass_phrase: 'yourpassphrase' # required for creating tokens # Additional public keys are used to verify signature of incoming tokens, if the key provided in "public_key" configuration node doesn't verify the token additional_public_keys: - '%kernel.project_dir%/config/jwt/public1.pem' - '%kernel.project_dir%/config/jwt/public2.pem' - '%kernel.project_dir%/config/jwt/public3.pem' ``` -------------------------------- ### Full Default Configuration Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst This configuration shows all available default settings for the bundle, including token TTL, clock skew, and various token extraction methods. ```yaml # config/packages/lexik_jwt_authentication.yaml # ... lexik_jwt_authentication: secret_key: ~ public_key: ~ pass_phrase: ~ token_ttl: 3600 # token TTL in seconds, defaults to 1 hour clock_skew: 0 allow_no_expiration: false # set to true to allow tokens without exp claim # token encoding/decoding settings encoder: # token encoder/decoder service - default implementation based on the lcobucci/jwt library service: lexik_jwt_authentication.encoder.lcobucci # encryption algorithm used by the encoder service signature_algorithm: RS256 # token extraction settings token_extractors: # look for a token as Authorization Header authorization_header: enabled: true prefix: Bearer name: Authorization # check token in a cookie cookie: enabled: false name: BEARER # check token in query string parameter query_parameter: enabled: false name: bearer # check token in a cookie split_cookie: enabled: false cookies: - jwt_hp - jwt_s # remove the token from the response body when using cookies remove_token_from_body_when_cookies_used: true # invalidate the token on logout by storing it in the cache blocklist_token: enabled: true cache: cache.app ``` -------------------------------- ### Minimal Configuration with HMAC Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Configure the bundle using a simple secret key for HMAC-based token creation and verification. ```yaml # config/packages/lexik_jwt_authentication.yaml #... lexik_jwt_authentication: secret_key: yoursecret ``` -------------------------------- ### Create Authenticated Client via Login Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/3-functional-testing.rst This helper method creates a functional test client and authenticates it by performing a login request. It then sets the Authorization header with the obtained JWT token. ```php /** * Create a client with a default Authorization header. * * @param string $username * @param string $password * * @return \Symfony\Bundle\FrameworkBundle\Client */ protected function createAuthenticatedClient($username = 'user', $password = 'password') { $client = static::createClient(); $client->jsonRequest( 'POST', '/api/login_check', [ 'username' => $username, 'password' => $password, ] ); $data = json_decode($client->getResponse()->getContent(), true); $client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $data['token'])); return $client; } /** * test getPagesAction */ public function testGetPages() { $client = $this->createAuthenticatedClient(); $client->jsonRequest('GET', '/api/pages'); // ... ``` -------------------------------- ### Run Test Suite with Composer Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/CONTRIBUTING.md Execute the project's test suite to ensure all tests pass before submitting changes. ```bash $ composer test ``` -------------------------------- ### Load and Convert Private Key to JWK Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst This command loads a private key, converts it to JWK format, and optionally sets a random ID, algorithm, and usage. It's a step in manual configuration migration. ```sh # We first need to convert the private key to a JWK. # If the private key is encrypted, you must provide the passphrase. # We take the opportunity to generate a random ID for the key and set the algorithm and the usage. # This is not mandatory, but it is a good practice. ./jose.phar key:load:key --random_id --use=sig --alg=RS256 --secret="testing" config/jwt/private.pem > config/jwt/signature.jwk ``` -------------------------------- ### Enable Token Blocklist Configuration Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/11-invalidate-token.rst Enable the token blocklist feature and specify the cache service to use for storing blocked token IDs. ```yaml lexik_jwt_authentication: # ... blocklist_token: enabled: true cache: cache.app ``` -------------------------------- ### Configure JWT Secret Key, Public Key, and Passphrase Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Set the paths to your JWT secret and public keys, and the passphrase in your .env file. These are required for token creation and verification. ```bash JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE= ``` -------------------------------- ### Enable Encryption Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Use this command to enable encryption features in the Web-Token library when in debug mode. ```sh bin/console lexik:jwt:enable-encryption ``` -------------------------------- ### Configure Web-Token Encoder and Access Token Parameters Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst This YAML configuration sets the Web-Token encoder and enables access token issuance and verification with specified algorithms and keys. ```yaml lexik_jwt_authentication: encoder: service: lexik_jwt_authentication.encoder.web_token # We use the Web-Token encoder access_token_issuance: enabled: true signature: algorithm: 'RS256' key: 'env(file:SIGNATURE_KEY)' access_token_verification: enabled: true signature: allowed_algorithms: ['RS256'] keyset: 'env(file:SIGNATURE_KEYSET)' ``` -------------------------------- ### Configure Symfony Security for JWT Login Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Set up the security.yaml file to define firewalls for login and API access, and configure JSON login with success and failure handlers. Ensure the firewall order is correct. ```yaml security: enable_authenticator_manager: true # Only for Symfony 5.4 # ... firewalls: login: pattern: ^/api/login stateless: true json_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure api: pattern: ^/api stateless: true jwt: ~ access_control: - { path: ^/api/login, roles: PUBLIC_ACCESS } - { path: ^/api, roles: IS_AUTHENTICATED_FULLY } ``` -------------------------------- ### Make JWT App Executable Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Set the downloaded JWT App PHAR file as executable to use its key management functionalities. ```sh chmod +x jose.phar ``` -------------------------------- ### Configure JWT Authentication in Lexik Bundle Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Configure the JWT secret key, public key, passphrase, and token TTL in the lexik_jwt_authentication.yaml configuration file. The secret and public keys are resolved from environment variables. ```yaml lexik_jwt_authentication: secret_key: '%env(resolve:JWT_SECRET_KEY)%' # required for token creation public_key: '%env(resolve:JWT_PUBLIC_KEY)%' # required for token verification pass_phrase: '%env(JWT_PASSPHRASE)%' # required for token creation token_ttl: 3600 # in seconds, default is 3600 ``` -------------------------------- ### Configure Authentication Success Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Configure a service to listen for the AUTHENTICATION_SUCCESS event to add public data to the JWT response. ```yaml # config/services.yaml services: acme_api.event.authentication_success_listener: class: App\EventListener\AuthenticationSuccessListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse } ``` -------------------------------- ### Configure JWT User Provider Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/8-jwt-user-provider.rst Configure the security.yaml file to use the lexik_jwt provider for user authentication. ```yaml security: providers: jwt: lexik_jwt: ~ ``` -------------------------------- ### Configure Custom Cache Pool for Blocklist Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/11-invalidate-token.rst Configure a specific cache pool, such as Redis, to be used for the token blocklist storage. ```yaml framework: # ... cache: default_redis_provider: 'redis://localhost' pools: block_list_token_cache_pool: adapter: cache.adapter.redis # ... blocklist_token: enabled: true cache: block_list_token_cache_pool ``` -------------------------------- ### Handle Authentication Success Response Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/7-manual-token-creation.rst Manually authenticate a user and return the same response as the login form by using the AuthenticationSuccessHandler. Ensure the user is fetched before calling this method. ```php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Security\Core\User\UserInterface; use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler; class FooController extends Controller { public function fooAction(AuthenticationSuccessHandler $authenticationSuccessHandler): JsonResponse { $user = ...; // Fetch user return $authenticationSuccessHandler->handleAuthenticationSuccess($user); } } ``` -------------------------------- ### Configure Authentication Failure Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Configure a service to listen for the AUTHENTICATION_FAILURE event to customize the failure response body. ```yaml # config/services.yaml services: acme_api.event.authentication_failure_listener: class: App\EventListener\AuthenticationFailureListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_failure, method: onAuthenticationFailureResponse } ``` -------------------------------- ### Generate SSL Keys for JWT Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Generate the necessary public and private SSL keys for JWT signing and verification using the console command. Keys are typically saved in config/jwt/. ```bash $ php bin/console lexik:jwt:generate-keypair ``` -------------------------------- ### Obtain JWT Token using cURL (Windows) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Use cURL on Windows to send a POST request to the login check endpoint with JSON credentials to obtain a JWT token. Note the different escaping for JSON data. ```bash C:\> curl -X POST -H "Content-Type: application/json" https://localhost/api/login_check --data {"username":"johndoe","password":"test"} ``` -------------------------------- ### Configure Firewall for Logout Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/11-invalidate-token.rst Enable the logout functionality in the firewall configuration to trigger token invalidation on logout. ```yaml security: enable_authenticator_manager: true firewalls: api: ... jwt: ~ logout: path: app_logout ``` -------------------------------- ### Generate Octet (Symmetric) Public Keyset Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a random octet (symmetric) public keyset with a specified number of private keys and key size. Use this for manual configuration migration. ```sh ./jose.phar keyset:generate:oct --random_id --use=sig --alg=HS256 3 256 > config/jwt/signature.jwkset ``` -------------------------------- ### Define Environment Variables for JWT Keys Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst This configuration snippet in services.yaml defines environment variables to load the signature key and keyset from specified file paths. ```yaml # config/services.yaml parameters: env(SIGNATURE_KEY): '%kernel.project_dir%/config/jwt/signature.jwk' env(SIGNATURE_KEYSET): '%kernel.project_dir%/config/jwt/signature.jwkset' ``` -------------------------------- ### Configure JWT Authenticated Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Configure a service to listen for the JWT_AUTHENTICATED event to customize the security token. ```yaml # config/services.yaml services: acme_api.event.jwt_authenticated_listener: class: App\EventListener\JWTAuthenticatedListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_authenticated, method: onJWTAuthenticated } ``` -------------------------------- ### Generate OKP (Ed25519) Public Keyset Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a random OKP (Ed25519) public keyset with a specified number of private keys and curve name. Use this for manual configuration migration. ```sh ./jose.phar keyset:generate:okp --random_id --use=sig --alg=ED25519 3 Ed25519 > config/jwt/signature.jwkset ``` -------------------------------- ### Rotate Keyset to Add Signature Private Key Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Rotates the existing keyset to include the signature private key. This command is part of the manual migration process. ```sh ./jose.phar keyset:rotate `cat config/jwt/signature.jwkset` `cat config/jwt/signature.jwk` > config/jwt/signature.jwkset ``` -------------------------------- ### Register Lexik JWT Authentication Bundle Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Register the bundle in your Symfony application's config/bundles.php file. This step is often handled automatically by Symfony Flex. ```php return [ //... Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], ]; ``` -------------------------------- ### Generate RSA Public Keyset Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a random RSA public keyset with a specified number of private keys and key size. Use this for manual configuration migration. ```sh # Next, we generate a random public keyset containing 3 private key. # Please use the same algorithm as the one used for the private key. ./jose.phar keyset:generate:rsa --random_id --use=sig --alg=RS256 --size 3 4096 > config/jwt/signature.jwkset ``` -------------------------------- ### Generate Test JWT Keys Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/3-functional-testing.rst Use OpenSSL to generate private and public keys for testing JWT authentication. These keys should be stored securely. ```terminal $ openssl genrsa -out config/jwt/private-test.pem -aes256 4096 $ openssl rsa -pubout -in config/jwt/private-test.pem -out config/jwt/public-test.pem ``` -------------------------------- ### Create JWT with Custom Payload Programmatically Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst When creating JWT tokens programmatically, use `createFromPayload` to include custom data. ```php $payload = ['foo' => 'bar']; $jwt = $this->container->get('lexik_jwt_authentication.jwt_manager')->createFromPayload($user, $payload); ``` -------------------------------- ### Configure Custom JWT Encoder Service Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/5-encoder-service.rst Configure the bundle to use your custom encoder service by specifying its class name in the configuration. This ensures the bundle utilizes your implementation for JWT encoding and decoding. ```yaml lexik_jwt_authentication: # ... encoder: service: App\Encoder\NixillaJWTEncoder ``` -------------------------------- ### Obtain JWT Token using cURL (Linux/macOS) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Use cURL to send a POST request to the login check endpoint with JSON credentials to obtain a JWT token. Ensure the Content-Type header is set to application/json. ```bash $ curl -X POST -H "Content-Type: application/json" https://localhost/api/login_check -d '{"username":"johndoe","password":"test"}' ``` -------------------------------- ### Configure API Platform JWT Authentication Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst Customize API Platform integration with JWT authentication by specifying the check path, username path, and password path in the lexik_jwt_authentication.yaml configuration. ```yaml lexik_jwt_authentication: # ... api_platform: check_path: /api/login_check username_path: email password_path: security.credentials.password ``` -------------------------------- ### Override JWT Configuration for Testing Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/3-functional-testing.rst Configure the Lexik JWT Authentication Bundle in `config_test.yml` to use the generated test keys. Ensure the paths to the private and public keys are correctly specified. ```yaml # config/test/lexik_jwt_authentication.yaml lexik_jwt_authentication: secret_key: '%kernel.project_dir%/config/jwt/private-test.pem' public_key: '%kernel.project_dir%/config/jwt/public-test.pem ``` -------------------------------- ### Before: Event Listener for JWTCreatedEvent (1.x) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/UPGRADE-2.0.md This PHP code shows an event listener for `lexik_jwt_authentication.on_jwt_created` in version 1.x, where the Request object could be directly retrieved from the event. ```yaml services: jwt_event_listener: class: AppBundle\EventListener\JWTCreatedListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated } ``` ```php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent; class JWTCreatedListener { public function onJWTCreated(JWTCreatedEvent $event) { $request = $event->getRequest(); } } ``` -------------------------------- ### Configuring JWT Not Found Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst YAML configuration to register a custom listener for the JWT_NOT_FOUND event. ```yaml services: acme_api.event.jwt_notfound_listener: class: App\EventListener\JWTNotFoundListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_not_found, method: onJWTNotFound } ``` -------------------------------- ### Configure JWT Created Event Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Register a listener for the JWT_CREATED event in services.yaml to customize the JWT payload or header. ```yaml services: acme_api.event.jwt_created_listener: class: App\EventListener\JWTCreatedListener arguments: [ '@request_stack' ] tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated } ``` -------------------------------- ### Create Authenticated Client with Direct JWT Encoding Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/3-functional-testing.rst This method generates a JWT token directly using the JWT encoder and attaches it to the client's Authorization header. It's useful for end-to-end testing scenarios where direct token manipulation is needed. ```php use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface; protected static function createAuthenticatedClient(array $claims) { $client = self::createClient(); $encoder = $client->getContainer()->get(JWTEncoderInterface::class); $client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $encoder->encode($claims))); return $client; } ``` -------------------------------- ### Generate OKP Signature Private Key Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a new OKP (octet key pair) private key for signature purposes, compatible with ED25519 algorithm. The key is saved to a specified JWK file. ```sh ./jose.phar key:generate:okp --random_id --use=sig --alg=ED25519 Ed25519 > config/jwt/signature.jwk ``` -------------------------------- ### Process Code with Rector Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/CONTRIBUTING.md Utilize Rector to update code to align with current PHP version features and best practices. ```bash $ vendor/bin/rector process ``` -------------------------------- ### Handle Authentication Success with Existing JWT Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/7-manual-token-creation.rst Pass an existing JWT token to the handleAuthenticationSuccess method to include it in the authentication response. ```php return $authenticationSuccessHandler->handleAuthenticationSuccess($user, $jwt); ``` -------------------------------- ### Generate Elliptic Curve (EC) Public Keyset Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a random elliptic curve (EC) public keyset with a specified number of private keys and curve name. Use this for manual configuration migration. ```sh ./jose.phar keyset:generate:ec --random_id --use=sig --alg=ES256 3 P-256 > config/jwt/signature.jwkset ``` -------------------------------- ### Create JWT Token for a User Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/7-manual-token-creation.rst Use the JWTManager service to create a JWT token for a given user. This dispatches JWT_CREATED and JWT_ENCODED events but not AUTHENTICATION_SUCCESS. ```php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Security\Core\User\UserInterface; use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; class ApiController extends Controller { public function getTokenUser(UserInterface $user, JWTTokenManagerInterface $JWTManager): JsonResponse { // ... return new JsonResponse(['token' => $JWTManager->create($user)]); } } ``` -------------------------------- ### Configure Firewall to Use Custom Authenticator Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/6-extending-jwt-authenticator.rst Assign your custom authenticator to a specific firewall in security.yaml. This ensures that the custom logic is applied to requests matching the firewall pattern. ```yaml # config/packages/security.yaml security: # ... firewalls: # ... api: pattern: ^/api stateless: true jwt: authenticator: app.custom_authenticator ``` -------------------------------- ### Custom User Class Implementation Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/8-jwt-user-provider.rst Implement the JWTUserInterface to create a custom user class that can be instantiated from a JWT payload. This allows for custom user logic and data handling. ```php namespace App\Security; final class User implements JWTUserInterface { // Your own logic public function __construct($username, array $roles, $email) { $this->username = $username; $this->roles = $roles; $this->email = $email; } public static function createFromPayload($username, array $payload) { return new self( $username, $payload['roles'], // Added by default $payload['email'] // Custom ); } } ``` -------------------------------- ### Set Custom Response on Authentication Failure Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Implement a listener for the AuthenticationFailureEvent to define a custom JSON response and status code for failed authentication attempts. ```php // src/App/EventListener/AuthenticationFailureListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent; ``` -------------------------------- ### Register Custom Authenticator in services.yaml Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/6-extending-jwt-authenticator.rst Configure your custom authenticator service by extending the default JWT authenticator. This makes your custom class available for use. ```yaml # config/services.yaml services: app.custom_authenticator: class: App\Security\CustomAuthenticator parent: lexik_jwt_authentication.security.jwt_authenticator ``` -------------------------------- ### Add Client IP to JWT Payload and Custom Header Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Listen to the JWT_CREATED event to add the client's IP address to the payload and set a custom 'cty' header. ```php // src/App/EventListener/JWTCreatedListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent; use Symfony\Component\HttpFoundation\RequestStack; /** * @var RequestStack */ private $requestStack; /** * @param RequestStack $requestStack */ public function __construct(RequestStack $requestStack) { $this->requestStack = $requestStack; } /** * @param JWTCreatedEvent $event * * @return void */ public function onJWTCreated(JWTCreatedEvent $event) { $request = $this->requestStack->getCurrentRequest(); $payload = $event->getData(); $payload['ip'] = $request->getClientIp(); $event->setData($payload); $header = $event->getHeader(); $header['cty'] = 'JWT'; $event->setHeader($header); } ``` -------------------------------- ### Fix Coding Standards with ECS Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/CONTRIBUTING.md Use the symplify/easy-coding-standard tool to automatically fix code style issues according to PSR-12 standards. ```bash $ vendor/bin/ecs --fix ``` -------------------------------- ### Configuring JWT Expired Token Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst YAML configuration to register a custom listener for the JWT_EXPIRED event. ```yaml services: acme_api.event.jwt_expired_listener: class: App\EventListener\JWTExpiredListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_expired, method: onJWTExpired } ``` -------------------------------- ### Configuring JWT Invalid Token Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst YAML configuration to register a custom listener for the JWT_INVALID event. ```yaml services: acme_api.event.jwt_invalid_listener: class: App\EventListener\JWTInvalidListener tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_invalid, method: onJWTInvalid } ``` -------------------------------- ### Configure Custom User Class Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/8-jwt-user-provider.rst Specify your custom user class in security.yaml to be used by the JWT provider. This ensures that your custom user logic is applied during authentication. ```yaml providers: # ... jwt: lexik_jwt: class: App\Security\User ``` -------------------------------- ### Enable Split Cookie Token Extractor Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Configure the bundle to extract JWT tokens using split cookies. This approach can offer benefits for stateless SPAs. Session cookies can be created by setting the signature cookie lifetime to 0. ```yaml token_extractors: split_cookie: ``` -------------------------------- ### Generate OCT Signature Private Key Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a new OCT (octet sequence) private key for signature purposes, compatible with HS256 algorithm. The key is saved to a specified JWK file. ```sh ./jose.phar key:generate:oct --random_id --use=sig --alg=HS256 256 > config/jwt/signature.jwk ``` -------------------------------- ### Inject TokenStorageInterface and JWTTokenManagerInterface Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/9-access-authenticated-jwt-token.rst Inject the necessary interfaces into your class constructor to access JWT token functionalities. ```php use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; public function __construct(TokenStorageInterface $tokenStorageInterface, JWTTokenManagerInterface $jwtManager) { $this->jwtManager = $jwtManager; $this->tokenStorageInterface = $tokenStorageInterface; } ``` -------------------------------- ### After: Event Listener for JWTCreatedEvent (2.0) Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/UPGRADE-2.0.md This PHP code demonstrates the updated event listener pattern in version 2.0, requiring injection of RequestStack to access the current Request. ```yaml services: jwt_event_listener: class: AppBundle\EventListener\JWTCreatedListener arguments: [ '@request_stack' ] tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated } ``` ```php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent; use Symfony\Component\HttpFoundation\RequestStack; class JWTCreatedListener { private $requestStack; public function __construct(RequestStack $requestStack) { $this->requestStack = $requestStack; } public function onJWTCreated(JWTCreatedEvent $event) { $request = $this->requestStack->getCurrentRequest(); } } ``` -------------------------------- ### Generate RSA Signature Private Key Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a new RSA private key for signature purposes, compatible with RS256 algorithm. The key is saved to a specified JWK file. ```sh ./jose.phar key:generate:rsa --random_id --use=sig --alg=RS256 --size 4096 > config/jwt/signature.jwk ``` -------------------------------- ### Add User Roles to JWT Response Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Use the AuthenticationSuccessEvent to add custom data, like user roles, to the JSON response body upon successful authentication. ```php // src/App/EventListener/AuthenticationSuccessListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent; /** * @param AuthenticationSuccessEvent $event */ public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event) { $data = $event->getData(); $user = $event->getUser(); if (!$user instanceof UserInterface) { return; } $data['data'] = array( 'roles' => $user->getRoles(), ); $event->setData($data); } ``` -------------------------------- ### Update Security Configuration for Symfony 5.3+ JWT Authenticator Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/UPGRADE-2.12.md When using Symfony 5.3 or later, update your `security.yaml` to enable the new authenticator manager and configure the JWT authenticator. This replaces the older `guard` authenticator. ```yaml security: firewalls: api: pattern: ^/api guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator ``` ```yaml security: enable_authenticator_manager: true firewalls: api: pattern: ^/api jwt: ~ ``` -------------------------------- ### Assign JWT Provider to Firewall Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/8-jwt-user-provider.rst Assign the configured JWT user provider to a specific firewall in security.yaml. ```yaml security: firewalls: api: provider: jwt jwt: ~ ``` -------------------------------- ### Generate EC Signature Private Key Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/10-web-token.rst Generates a new EC (elliptic curve) private key for signature purposes, compatible with ES256 algorithm using the P-256 curve. The key is saved to a specified JWK file. ```sh ./jose.phar key:generate:ec --random_id --use=sig --alg=ES256 P-256 > config/jwt/signature.jwk ``` -------------------------------- ### Apache Configuration for Authorization Header Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/index.rst This configuration is necessary for Apache servers to correctly pass the Authorization header to your Symfony application when using JWT authentication. ```apache SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ``` -------------------------------- ### Obtain JWT String After Encoding Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Use the JWTEncodedEvent to access the JWT string immediately after it has been created. ```php // src/App/EventListener/JWTEncodedListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTEncodedEvent; /** * @param JWTEncodedEvent $event */ public function onJwtEncoded(JWTEncodedEvent $event) { $token = $event->getJWTString(); } ``` -------------------------------- ### Configure JWT Decoded Event Listener Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Register a listener for the JWT_DECODED event in services.yaml to perform custom validation on the decoded JWT payload. ```yaml # config/services.yaml services: acme_api.event.jwt_decoded_listener: class: App\EventListener\JWTDecodedListener arguments: [ '@request_stack' ] tags: - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_decoded, method: onJWTDecoded } ``` -------------------------------- ### Customizing Response When Token is Not Found Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst PHP code to set a custom JSON response with a 403 status code when no JWT is found in the request. ```php // src/App/EventListener/JWTNotFoundListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTNotFoundEvent; use Symfony\Component\HttpFoundation\JsonResponse; /** * @param JWTNotFoundEvent $event */ public function onJWTNotFound(JWTNotFoundEvent $event) { $data = [ 'status' => '403 Forbidden', 'message' => 'Missing token', ]; $response = new JsonResponse($data, 403); $event->setResponse($response); } ``` -------------------------------- ### Enable JWT Authenticator in Security Firewall Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Configures the security firewall to enable the JWT authenticator. The 'enable_authenticator_manager' option is specific to Symfony 5.4. ```yaml # config/packages/security.yaml security: enable_authenticator_manager: true # Only for Symfony 5.4 firewalls: api: # ... jwt: ~ # enables the jwt authenticator # Full config with defaults: # jwt: # provider: null (you can put provider here or just ignore this config) # authenticator: lexik_jwt_authentication.security.jwt_authenticator (default jwt authenticator) # ... ``` -------------------------------- ### Override getTokenExtractor for Custom Token Extraction Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/6-extending-jwt-authenticator.rst Customize how JWT tokens are extracted by overriding the getTokenExtractor method. This allows you to define specific extraction logic, such as using a different header or query parameter. ```php /** * @return TokenExtractor\TokenExtractorInterface */ protected function getTokenExtractor() { // Return a custom extractor, no matter of what are configured return new TokenExtractor\AuthorizationHeaderTokenExtractor('Token', 'Authorization'); // Or retrieve the chain token extractor for mapping/unmapping extractors for this authenticator $chainExtractor = parent::getTokenExtractor(); // Clear the token extractor map from all configured extractors $chainExtractor->clearMap(); // Or only remove a specific extractor $chainTokenExtractor->removeExtractor(function (TokenExtractor\TokenExtractorInterface $extractor) { return $extractor instanceof TokenExtractor\CookieTokenExtractor; }); // Add a new query parameter extractor to the configured ones $chainExtractor->addExtractor(new TokenExtractor\QueryParameterTokenExtractor('jwt')); // Return the chain token extractor with the new map return $chainExtractor; } ``` -------------------------------- ### Customizing Invalid Token Response Message and Status Code Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst PHP code to set a custom message and HTTP status code (403) for an invalid JWT. ```php // src/App/EventListener/JWTInvalidListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTInvalidEvent; use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse; /** * @param JWTInvalidEvent $event */ public function onJWTInvalid(JWTInvalidEvent $event) { $response = new JWTAuthenticationFailureResponse('Your token is invalid, please login again to get a new one', 403); $event->setResponse($response); } ``` -------------------------------- ### Programmatic Token Invalidation on Logout Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/11-invalidate-token.rst Manually dispatch the LogoutEvent to invalidate the token programmatically within a controller action. ```php use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Http\Event\LogoutEvent; //... class SecurityController { //... public function logout(Request $request, EventDispatcherInterface $eventDispatcher, TokenStorageInterface $tokenStorage) { $eventDispatcher->dispatch(new LogoutEvent($request, $tokenStorage->getToken())); return new JsonResponse(); } } ``` -------------------------------- ### Decode JWT Token Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/9-access-authenticated-jwt-token.rst Decode the JWT token from the current request using the injected JWTTokenManagerInterface and TokenStorageInterface. ```php $decodedJwtToken = $this->jwtManager->decode($this->tokenStorageInterface->getToken()); ``` -------------------------------- ### Add Additional Data to JWT Payload Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Use the JWTDecodedEvent to add custom data to the JWT payload. This data can then be accessed in your custom UserProvider. ```php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTDecodedEvent; /** * @param JWTDecodedEvent $event * * @return void */ public function onJWTDecoded(JWTDecodedEvent $event) { $payload = $event->getPayload(); $user = $this->userRepository->findOneByUsername($payload['username']); $payload['custom_user_data'] = $user->getCustomUserInformations(); $event->setPayload($payload); // Don't forget to regive the payload for next event / step } ``` -------------------------------- ### Customizing Response Message for Expired Token Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst PHP code to modify the existing response message when a JWT token has expired. ```php // src/App/EventListener/JWTExpiredListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTExpiredEvent; use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse; /** * @param JWTExpiredEvent $event */ public function onJWTExpired(JWTExpiredEvent $event) { /** @var JWTAuthenticationFailureResponse */ $response = $event->getResponse(); $response->setMessage('Your token is expired, please renew it.'); } ``` -------------------------------- ### Override JWT Expiration Date Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Customize the JWT expiration date calculation by setting a new expiration timestamp in the payload. ```php // src/App/EventListener/JWTCreatedListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent; /** * @param JWTCreatedEvent $event * * @return void */ public function onJWTCreated(JWTCreatedEvent $event) { $expiration = new \DateTime('+1 day'); $expiration->setTime(2, 0, 0); $payload = $event->getData(); $payload['exp'] = $expiration->getTimestamp(); $event->setData($payload); } ``` -------------------------------- ### Validate Client IP in Decoded JWT Payload Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Access the decoded JWT payload within the JWT_DECODED event listener to perform validation, such as checking the client IP. ```php // src/App/EventListener/JWTDecodedListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTDecodedEvent; /** * @param JWTDecodedEvent $event * * @return void */ public function onJWTDecoded(JWTDecodedEvent $event) { $request = $this->requestStack->getCurrentRequest(); $payload = $event->getPayload(); ``` -------------------------------- ### Disable Token Removal from Body with Cookies Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/1-configuration-reference.rst Controls whether the JWT token is removed from the response body when using cookies. Setting this to false allows the token to remain in the body. ```yaml remove_token_from_body_when_cookies_used: false ``` -------------------------------- ### Keep UUID in Authenticated Token Source: https://github.com/lexik/lexikjwtauthenticationbundle/blob/3.x/Resources/doc/2-data-customization.rst Use the JWTAuthenticatedEvent to add attributes, such as a UUID, from the JWT payload to the authenticated token. ```php // src/App/EventListener/JWTAuthenticatedListener.php use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTAuthenticatedEvent; /** * @param JWTAuthenticatedEvent $event * * @return void */ public function onJWTAuthenticated(JWTAuthenticatedEvent $event) { $token = $event->getToken(); $payload = $event->getPayload(); $token->setAttribute('uuid', $payload['uuid']); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.