Lexikjwtauthenticationbundle: How to change format of token response?

Created on 7 Jul 2017  路  12Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hi,

I need to be able to change the format of the response when a token is created. I have tried through event handlers but it is not working. Currently the format defaults to:

{ "token" : "generatedtokenhere...." }

and I need to change it to something like:

{ "code" : 200,
"payload" : {
"token" : "generatedtokenhere..."
}
}

Is there a way to do that? Thank you!

Most helpful comment

Listener registration:

# app/config/services.yml
services:
    app.listener.authentication_success_response:
        class: AppBundle\EventListener\AuthenticationSuccessListener
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }

Listener code:

# src/AppBundle/EventListener/AuthenticationSuccessListener.php
namespace AppBundle\EventListener;

use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;

class AuthenticationSuccessListener
{
    public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event)
    {
        $event->setData([
            'code' => $event->getResponse()->getStatusCode(),
            'payload' => $event->getData(),
        ]);
    }
}

Result:

{
    "code": 200,
    "payload": {
        "token": "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJqb2huIiwiaWF0IjoxNDk5NTI2ODg0LCJleHAiOjE0OTk1MzA0ODR9.bMOILED3urWABRnPnAQ8_KqWPg7uweqCA9Pyz8gbi7ufiLsMuvVvYVqNf7qy9iiYqDNFLcrmLYp15b3_x4cfuWn4dwd4qg9GPiFMefwDIBk00OEweK_j2V88R6NzvwYWbWd7Y4j5FRtF1ZjqMPv7aHLYanfC7eBW5SP1lpo017nYzZAzQ2MVOGvgcVdGZ8rcdLKRNcMmYodfJXvpGg564AjaDP9azUV-b40wOVWRitDvqeDMRpeV1EjiOkfrONjqSCVqQ09_qMX82HN17S1R9zmJwuw1zs5Lf0Ql5kRs6MHll0zEukkpstGQ9Pfp6jetQHZ0os7ZuEvu-z1yMgKTRr_Ifmm3YnX5E8yOQRcetw5aWVSf0eUXpXRa4M1x0CmPwJnTBnkhVMNO6BUkMS44h0iisRuC9aiC-uSIbPskil7oaEhnhT7qu38nnYfklkHM8TLHVtR5iP6mvh_VvM9EwZy37reusISlIbGEAkOkPGSVZz_wGO8N7wwCKs6lx4zeoTpdcIR7oGKLDZbS0oQ4eO9kHUEgbpBWdcTwXh8rVSyWIjPAkgpsI8Yvf1S38c5_Cmdn61Z2grlBPu7DTWQKh7AmUQw20iDv268nBQ3bvVmv_miecPkc13HMLzyb9Ibl6XuuAhDJNntP6Pf6KqfXyg3ktTmETPL5gh9jEehhT7U"
    }
}

Isn't this what you are looking for?

All 12 comments

Yes but that's not what I need. I need to change the format of the JSON response when a token is created. I am already using that to add some data to the response, but in my application all JSON response need to start with { "code" : } and the default response starts with { "token" : } and you can't seem to modify that format. I need to add the code field to the response (and not in the public payload body.)

Listener registration:

# app/config/services.yml
services:
    app.listener.authentication_success_response:
        class: AppBundle\EventListener\AuthenticationSuccessListener
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }

Listener code:

# src/AppBundle/EventListener/AuthenticationSuccessListener.php
namespace AppBundle\EventListener;

use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;

class AuthenticationSuccessListener
{
    public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event)
    {
        $event->setData([
            'code' => $event->getResponse()->getStatusCode(),
            'payload' => $event->getData(),
        ]);
    }
}

Result:

{
    "code": 200,
    "payload": {
        "token": "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJqb2huIiwiaWF0IjoxNDk5NTI2ODg0LCJleHAiOjE0OTk1MzA0ODR9.bMOILED3urWABRnPnAQ8_KqWPg7uweqCA9Pyz8gbi7ufiLsMuvVvYVqNf7qy9iiYqDNFLcrmLYp15b3_x4cfuWn4dwd4qg9GPiFMefwDIBk00OEweK_j2V88R6NzvwYWbWd7Y4j5FRtF1ZjqMPv7aHLYanfC7eBW5SP1lpo017nYzZAzQ2MVOGvgcVdGZ8rcdLKRNcMmYodfJXvpGg564AjaDP9azUV-b40wOVWRitDvqeDMRpeV1EjiOkfrONjqSCVqQ09_qMX82HN17S1R9zmJwuw1zs5Lf0Ql5kRs6MHll0zEukkpstGQ9Pfp6jetQHZ0os7ZuEvu-z1yMgKTRr_Ifmm3YnX5E8yOQRcetw5aWVSf0eUXpXRa4M1x0CmPwJnTBnkhVMNO6BUkMS44h0iisRuC9aiC-uSIbPskil7oaEhnhT7qu38nnYfklkHM8TLHVtR5iP6mvh_VvM9EwZy37reusISlIbGEAkOkPGSVZz_wGO8N7wwCKs6lx4zeoTpdcIR7oGKLDZbS0oQ4eO9kHUEgbpBWdcTwXh8rVSyWIjPAkgpsI8Yvf1S38c5_Cmdn61Z2grlBPu7DTWQKh7AmUQw20iDv268nBQ3bvVmv_miecPkc13HMLzyb9Ibl6XuuAhDJNntP6Pf6KqfXyg3ktTmETPL5gh9jEehhT7U"
    }
}

Isn't this what you are looking for?

That does not work for me :( I actually already had this listener setup, but copied this code directly and still get just a { "token" : } response. Looking at the AuthenticationSuccessEvent class it has a getResponse() method but not a setResponse(), which is where I think you would set this.

My composer.json has "lexik/jwt-authentication-bundle": "~2.0"

I did try the code I given and the result is the one I pasted, no need for a setResponse(), setData() is enough. I pushed the working example at https://github.com/chalasr/lexik-jwt-authentication-sandbox/tree/customize-response-body, either there is something wrong in the way you're using the bundle (so that the event is not dispatched) or the listener is misconfigured.
Anyway we'll need that you provide a reproducer e.g. a fork of the symfony standard edition or the lexik-jwt-authentication-sandbox with the code necessary to reproduce the issue.

Ok thank you I will take a look at the example.

I did confirm the event is being called by writing to a log file and the even is definitely firing. I will double check the configuration and will let you know. I appreciate your help!

Ok, a little closer. Here is my entry in services.yml:

app.event.authentication_success_response:
        class: AppBundle\EventListener\AuthenticationListener
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }

And the code:

<?php

namespace AppBundle\EventListener;

use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse;

class AuthenticationListener
{

    /**
    * @param AuthenticationSuccessEvent $event
    */
   public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event)
   {

        echo "\nHERE AT AuthenticationSuccessResponse\n";

        $event->setData([
            'code' => $event->getResponse()->getStatusCode(),
            'payload' => $event->getData(),
        ]);

   }

   /**
    * @param AuthenticationFailureEvent $event
    */
   public function onAuthenticationFailureResponse(AuthenticationFailureEvent $event)
   {
       $response = new JWTAuthenticationFailureResponse('Authentication failed', 401);
       $event->setResponse($response);
   }
}

And this is the output I get (I've stripped out the token so save space):

HERE AT AuthenticationSuccessResponse
{"token":"{token}","code":200,"payload":{"token":"{token}"}}

Previously I had a check of the user object in the event and it was not validating as an instance of UserInterface so was returning before modifying the response. I removed it (not really needed at this point) and now it is just appending the modification to the response instead of replacing it.

Could you run composer show lexik/jwt-authentication-bundle to get the installed version and give us the result?

name     : lexik/jwt-authentication-bundle
descrip. : This bundle provides JWT authentication for your Symfony REST API
keywords : Authentication, JWS, api, bundle, jwt, rest, symfony
versions : * v2.0.2
type     : symfony-bundle
license  : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
source   : [git] https://github.com/lexik/LexikJWTAuthenticationBundle.git 601d274ab15b34f685bf37c6afe21b58bfc63ac7
dist     : [zip] https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/601d274ab15b34f685bf37c6afe21b58bfc63ac7 601d274ab15b34f685bf37c6afe21b58bfc63ac7
names    : lexik/jwt-authentication-bundle

autoload
psr-4
Lexik\Bundle\JWTAuthenticationBundle\ => .
exclude-from-classmap

requires
namshi/jose ^7.2
php ^5.5|^7.0
symfony/console ^2.8|^3.0
symfony/framework-bundle ^2.8|^3.0
symfony/security-bundle ^2.8|^3.0

requires (dev)
friendsofphp/php-cs-fixer ^1.1
lcobucci/jwt ~3.2
phpunit/phpunit ^4.1|^5.0
symfony/browser-kit ^2.8|^3.0
symfony/phpunit-bridge ^2.8|^3.0

suggests
gesdinet/jwt-refresh-token-bundle Implements a refresh token system over Json Web Tokens in Symfony
lcobucci/jwt For using the LcobucciJWTEncoder
spomky-labs/lexik-jose-bridge Provides a JWT Token encoder with encryption support

Ok just realized I am not on the latest version (thought I was.) Let me upgrade and try again!

Ok that works! Thank you! I'm sorry...I thought I WAS on the latest version :/ Closing the issue.

Hi guys ,

I am working right now with a REST API,

I would like to know how to generate a token with lexikauthbundle based on a specific role

e.g : ROLE_SUPER_ADMIN : i want to send user and pass and generate a token if the user has the role SUPER_ADMIN for example else a json code error must be returned

hope my idea was clear

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Walkoss picture Walkoss  路  5Comments

tsdevelopment picture tsdevelopment  路  4Comments

hiromik picture hiromik  路  3Comments

ghost picture ghost  路  5Comments

pbalan picture pbalan  路  5Comments