Set up JWT authentication with Symfony using the LexikJWTAuthenticationBundle

Aghar Saifeddine
2 min readMar 11, 2024

--

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Now, let’s proceed with setting up JWT authentication with Symfony using the LexikJWTAuthenticationBundle, you can follow these steps:

1- Install the LexikJWTAuthenticationBundle using Composer:

composer require “lexik/jwt-authentication-bundle”

2- Generate keypairs for encoding JWTs:

php bin/console lexik:jwt:generate-keypair

3- Configure SSL keys and JWT passphrase in your .env file:

###> lexik/jwt-authentication-bundle ###
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=<your passphrase here, it can be anything>
###< lexik/jwt-authentication-bundle ###

4- Configure LexikJWTAuthenticationBundle in config/packages/lexik_jwt_authentication.yaml:

lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600

5- Modify your security configuration in config/packages/security.yaml:

security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: username
firewalls:

main:
lazy: true
provider: app_user_provider
json_login:
check_path: /api/login_check
# username_path: email
# password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
jwt: ~
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall

# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true

# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }

6- Define the route for login check in config/routes.yaml:

api_login_check:
path: /api/login_check

Now, you can authenticate by sending a POST request (using postman) to /api/login_check with the following body:

{
“username”: “test@exemple.com”,
“password”: “123456”
}

The response will contain a JWT token

To authenticate future requests, include the token as a Bearer token in the Authorization header:

Authorization: Bearer <your token here>

That’s it!, by following these steps, you can set up JWT authentication in Symfony using the LexikJWTAuthenticationBundle.

--

--