<commit_before>Data customization and validation
=================================

**Careful**: Before you add your own custom data, know that the **JWT payload is not encrypted, it is only base64 encoded**. The token signature ensures its integrity (meaning it cannot be modified), but anyone can read its content (try it using a simple tool like [http://jwt.io/](http://jwt.io/)).

#### Events::JWT_CREATED - add data to the JWT payload

By default the JWT payload will contain the username and the token TTL,
but you can add your own data.

``` yaml
# services.yml
services:
    acme_api.event.jwt_created_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener
        arguments: [ '@request_stack' ] # Symfony 2.4+
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated }
```

Example 1 : add client ip to the encoded payload

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener.php

use Symfony\Component\HttpFoundation\RequestStack;

class JWTCreatedListener
{
    /**
     * @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)
    {
        // Symfony < 2.4
        $request = $event->getRequest();
        
        // Symfony 2.4+
        $request = $this->requestStack->getCurrentRequest();

        $payload       = $event->getData();
        $payload['ip'] = $request->getClientIp();

        $event->setData($payload);
    }
}
```

Example 2 : override token expiration date calcul to be more flexible

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener.php
class JWTCreatedListener
{  
    /**
     * @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);
    }
}
```

#### Events::JWT_DECODED - validate data in the JWT payload

You can access the jwt payload once it has been decoded to perform you own additional validation.

``` yaml
# services.yml
services:
    acme_api.event.jwt_decoded_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTDecodedListener
        arguments: [ '@request_stack' ] # Symfony 2.4+
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_decoded, method: onJWTDecoded }
```

Example 3 : check client ip the decoded payload (from example 1)

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTDecodedListener.php
class JWTDecodedListener
{
    // ...
  
    /**
     * @param JWTDecodedEvent $event
     *
     * @return void
     */
    public function onJWTDecoded(JWTDecodedEvent $event)
    {
        // Symfony < 2.4
        $request = $event->getRequest();
        
        // Symfony 2.4+
        $request = $this->requestStack->getCurrentRequest();
        
        $payload = $event->getPayload();

        if (!isset($payload['ip']) || $payload['ip'] !== $request->getClientIp()) {
            $event->markAsInvalid();
        }
    }
}
```

#### Events::JWT_AUTHENTICATED - customize your authenticated token

You can add attributes to the token once it has been authenticated to allow JWT properties to be used by your application.

``` yaml
# services.yml
services:
    acme_api.event.jwt_authenticated_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTAuthenticatedListener
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_authenticated, method: onJWTAuthenticated }<commit_msg>Update mis-merged examples in README<commit_after>Data customization and validation
=================================

**Careful**: Before you add your own custom data, know that the **JWT payload is not encrypted, it is only base64 encoded**. The token signature ensures its integrity (meaning it cannot be modified), but anyone can read its content (try it using a simple tool like [http://jwt.io/](http://jwt.io/)).

#### Events::JWT_CREATED - add data to the JWT payload

By default the JWT payload will contain the username and the token TTL,
but you can add your own data.

``` yaml
# services.yml
services:
    acme_api.event.jwt_created_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener
        arguments: [ '@request_stack' ]
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated }
```

Example 1 : add client ip to the encoded payload

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener.php

use Symfony\Component\HttpFoundation\RequestStack;

class JWTCreatedListener
{
    /**
     * @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);
    }
}
```

Example 2 : override token expiration date calcul to be more flexible

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTCreatedListener.php
class JWTCreatedListener
{  
    /**
     * @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);
    }
}
```

#### Events::JWT_DECODED - validate data in the JWT payload

You can access the jwt payload once it has been decoded to perform you own additional validation.

``` yaml
# services.yml
services:
    acme_api.event.jwt_decoded_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTDecodedListener
        arguments: [ '@request_stack' ]
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_decoded, method: onJWTDecoded }
```

Example 3 : check client ip the decoded payload (from example 1)

``` php
// Acme\Bundle\ApiBundle\EventListener\JWTDecodedListener.php
class JWTDecodedListener
{
    // ...
  
    /**
     * @param JWTDecodedEvent $event
     *
     * @return void
     */
    public function onJWTDecoded(JWTDecodedEvent $event)
    {
        $request = $this->requestStack->getCurrentRequest();
        
        $payload = $event->getPayload();

        if (!isset($payload['ip']) || $payload['ip'] !== $request->getClientIp()) {
            $event->markAsInvalid();
        }
    }
}
```

#### Events::JWT_AUTHENTICATED - customize your authenticated token

You can add attributes to the token once it has been authenticated to allow JWT properties to be used by your application.

``` yaml
# services.yml
services:
    acme_api.event.jwt_authenticated_listener:
        class: Acme\Bundle\ApiBundle\EventListener\JWTAuthenticatedListener
        tags:
            - { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_authenticated, method: onJWTAuthenticated }
{'fraction_non_alphanumeric': 0.12210714742360312, 'fraction_numerical': 0.004091548395345864, 'mean_word_length': 2.9306532663316585, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '232803', 'n_tokens_mistral': 2389, 'n_tokens_neox': 2291, 'n_words': 590}