This bundle provides JWT (Json Web Token) authentication for your Pimcore API.
It is based on lexik/jwt-authentication-bundle
It is compatible and tested with PHP 7 and Pimcore 6.
Table of Contents
This module requires Pimcore 6 and openssl extension.
Create User class in Pimcore:
Register dependencies in app/AppKernel.php
:
public function registerBundlesToCollection(BundleCollection $collection)
{
// ...
if (class_exists('Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle')) {
$collection->addBundle(new Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle());
}
if (class_exists('Nelmio\CorsBundle\NelmioCorsBundle')) {
$collection->addBundle(new Nelmio\CorsBundle\NelmioCorsBundle());
}
}
Generate the SSH keys :
$ mkdir app/config/jwt
$ openssl genrsa -out app/config/jwt/private.pem -aes256 4096
$ openssl rsa -pubout -in app/config/jwt/private.pem -out config/jwt/public.pem
In case first openssl
command forces you to input password use following to get the private key decrypted
$ openssl rsa -in app/config/jwt/private.pem -out config/jwt/private2.pem
$ mv app/config/jwt/private.pem config/jwt/private.pem-back
$ mv app/config/jwt/private2.pem config/jwt/private.pem
Configure the SSH keys path in your app/config/lexik_jwt_authentication.yaml
:
lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/app/config/jwt/private.pem' # required for token creation
public_key: '%kernel.project_dir%/app/config/jwt/public.pem' # required for token verification
pass_phrase: 'your_secret_passphrase' # required for token creation, usage of an environment variable is recommended
token_ttl: 3600
Configure CORS configuration in app/config/nelmio_cors.yml
:
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: []
allow_headers: []
allow_methods: []
expose_headers: []
max_age: 0
hosts: []
origin_regex: false
forced_allow_origin_value: ~
paths:
'^/api/':
allow_origin: ['*']
allow_headers: ['*']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
max_age: 3600
Configure your app/config/security.yml
:
security:
# ...
providers:
pimcore_user_provider:
id: login_bundle.security.user_provider
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: pimcore_user_provider
json_login:
check_path: /api/login
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
provider: pimcore_user_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Configure yor app/config/config.yml
:
imports:
# ...
- { resource: lexik_jwt_authentication.yml }
- { resource: nelmio_cors.yml }
Configure your config/routing.yml
:
api_login_check:
path: /api/login
The first step is to authenticate the user using its credentials. A classical form_login on an anonymously accessible firewall will do perfect.
Just set the provided lexik_jwt_authentication.handler.authentication_success
service as success handler to
generate the token and send it as part of a json response body.
Store it (client side), the JWT is reusable until its ttl has expired (3600 seconds by default). Create in Pimcore panel an object of class User and fill its credentials.
Note: You can test getting the token with a simple curl command like this:
curl -X POST -H "Content-Type: application/json" http://localhost/api/login -d '{"username":"admin","password":"test"}'
If it works, you will receive something like this:
{
"token" : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE0MzQ3Mjc1MzYsInVzZXJuYW1lIjoia29ybGVvbiIsImlhdCI6IjE0MzQ2NDExMzYifQ.nh0L_wuJy6ZKIQWh6OrW5hdLkviTs1_bau2GqYdDCB0Yqy_RplkFghsuqMpsFls8zKEErdX5TYCOR7muX0aQvQxGQ4mpBkvMDhJ4-pE4ct2obeMTr_s4X8nC00rBYPofrOONUOR4utbzvbd4d2xT_tj4TdR_0tsr91Y7VskCRFnoXAnNT-qQb7ci7HIBTbutb9zVStOFejrb4aLbr7Fl4byeIEYgp2Gd7gY"
}
Simply pass the JWT on each request to the protected firewall, either as an authorization header or as a query parameter.
By default only the authorization header mode is enabled : Authorization: Bearer {token}
Each request after token expiration will result in a 401 response. Redo the authentication process to obtain a new token.
Maybe you want to use a refresh token to renew your JWT. In this case you can check JWTRefreshTokenBundle.
For more details head to LexikJWTAuthenticationBundle
This module respects PSR-2 code quality rule and our own PHPCS and PHPMD rulesets.
We are a Software House from Europe, existing from 2008 and employing about 150 people. Our core competencies are built around Magento, Pimcore and bespoke software projects (we love Symfony3, Node.js, Angular, React, Vue.js). We specialize in sophisticated integration projects trying to connect hardcore IT with good product design and UX.
We work for Clients like INTERSPORT, ING, Odlo, Onderdelenwinkel and CDP, the company that produced The Witcher game. We develop two projects: Open Loyalty - an open source loyalty program and Vue.js Storefront.
We are part of the OEX Group which is listed on the Warsaw Stock Exchange. Our annual revenue has been growing at a minimum of about 30% year on year.
Visit our website Divante.co for more information.