Seleccionar página
José

José

Co-founder | CTO Software Engineer

Más melómano que geek, aunque más de crear software que de otras muchas cosas

JWT | Laravel
Laravel Passport es el módulo oficial de Laravel que nos ayuda a la implementación de servicios de autenticación haciendo uso del protocolo OAuth2. Además, otra de las características de Laravel Passport es la implementación de JWT como estándar en la generación de tokens.

Laravel Passport añade una serie de claims por defecto, para cambiarlos solo tendremos que crear las siguientes clases y añadirlas a nuestro proyecto:

CustomAccessToken

Crearemos una nueva clase (CustomAccessToken) que extienda del AccessToken de Passport (Laravel\Passport\Bridge\AccessToken) y añadiremos nuestros claims haciendo uso del método “set(claim_name , claim_value)”


...

class CustomAccessToken extends \Laravel\Passport\Bridge\AccessToken
{

    /**
     * Generate a JWT from the access token
     *
     * @param CryptKey $privateKey
     *
     * @return Token
     */
    public function convertToJWT(CryptKey $privateKey)
    {
        return (new Builder())
            ->setAudience($this->getClient()->getIdentifier())
            ->setId($this->getIdentifier(), true)
            ->setIssuedAt(time())
            ->setNotBefore(time())
            ->setExpiration($this->getExpiryDateTime()->getTimestamp())
            ->setSubject($this->getUserIdentifier())
            ->set('custom_claim', 'https://www.sixphere.com')
            ->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
            ->getToken();
    }

}

CustomAccessTokenRepository

El segundo paso será extender la clase \Laravel\Passport\Bridge\AccessTokenRepository para que haga uso de CustomAccessToken.


...

class CustomAccessTokenRepository extends \Laravel\Passport\Bridge\AccessTokenRepository
{
     /**
     * {@inheritdoc}
     */
    public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
    {
        return new CustomAccessToken($userIdentifier, $scopes);
    }

}


CustomPassportServiceProvider

Extenderemos el service provider de Passport (\Laravel\Passport\PassportServiceProvider) y cambiaremos la implementación del método “makeAuthorizationServer()” para que añada nuestro CustomAccessTokenRepository.


...

class CustomPassportServiceProvider extends \Laravel\Passport\PassportServiceProvider
{

    /**
     * Interviene la instanciación del servidor de autenticación para cambiar el repositorio de tokens JWT
     *
     * @return \League\OAuth2\Server\AuthorizationServer
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function makeAuthorizationServer()
    {
        return new AuthorizationServer(
            $this->app->make(ClientRepository::class),
            $this->app->make( \App\Auth\Bridge\CustomAccessTokenRepository::class),  // This!!
            $this->app->make(ScopeRepository::class),
            $this->makeCryptKey('private'),
            app('encrypter')->getKey()
        );
    }
}

...

Para finalizar, lo añadiremos a la configuración de Laravel (server/config/app.php).


...

        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers...
         */

        App\Providers\CustomPassportServiceProvider::class, // This!!


        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
...


A partir de ahora, el payload de nuestros JWT generados con Passport contendrá los claims que hemos añadido.


{
  "aud": "2",
  "jti": "3df3d0b9be646d32d8aa4d8ddb72af2ed4752be07eb4ef752a46db59fefdd81d2643ada386246cd6",
  "iat": 1564683626,
  "nbf": 1564683626,
  "exp": 1596306026,
  "sub": "1",
  "custom_claim": "https://www.sixphere.com"
}

Share This