Navigation

Related Articles

Back to Latest Articles

LexikJWTAuthenticationBundle – Symfony2 REST API Authentification


Nicolas
LexikJWTAuthenticationBundle –...

Lexik vous présente aujourd’hui LexikJWTAuthenticationBundle, destiné à vous aider à mettre en place rapidement un système d’authentification entre votre API REST Symfony2 et d’éventuels clients Javascript (AngularJS, Ember.js, Backbone.js) ou mobiles.

Contexte

Les bonnes ressources concernant la mise en place d’une API REST Symfony2 ne manquent pas :

Mais peu d’informations claires sont disponibles sur l’authentification auprès d’une telle API. Et les stratégies dans ce domaine ne manquant pas, il va falloir faire un choix… Et chez Lexik on a  choisit le petit standard qui monte : le Json Web Token (JWT).

Pourquoi JWT ?

Les arguments en faveur de cette méthode sont nombreux : stateless, cross-domain, SPA et mobile ready, standardisé, testé et approuvé par une large communauté notamment AngularJS.

De plus, des projets PHP existent déjà pour nous faciliter le travail, notamment l’excellente libraire namshi/jose dont nous allons nous servir.

Bref, revenons au sujet de l’article ! Après l’avoir testé et mis en place sur plusieurs projets, nous sortons donc aujourd’hui le LexikJWTAuthenticationBundle.

Installation et configuration

Voir la marche à suivre indiquée dans le README du projet github.

Exemple d’utilisation avec AngularJS

Voir l’excellent post sur le blog de Auth0.

Test

Un projet sandbox est aussi disponible pour vous permettre de tester rapidement le système.

Show Comments (9)

Comments

  • Chris

    Hi. this is **exactly** what I need – but could not get it to work.

    1. using the code to generate the keys as you suggested, i got this whenever I logged in:
    Warning: openssl_sign(): supplied key param cannot be coerced into a private key

    The resultant token was missing the final part so nothing worked from then on.

    2. So I generated the keys differently:
    openssl genrsa -out app/var/jwt/private.pem 4096

    this then permitted login and produced a correctly formatted token

    3. However, could not get authentication to work. When I passed the token as a header, it was ignored completely (Authorization: Bearer ), when I passed it in the querystring it was picked up and processed, but always failed verify() in RSA.php – i checked and it was correctly loading the public key resource.

    Any tips?

    Thanks

    Chris

    • Article Author
  • Chris

    Hi. Further work showed the problem – if you are using a querystring at least (not sure about the headers). The passed token has escaped slashes, so if you pass that token back again it needs to be unescaped (eg stripslashes)

    • Article Author
  • Laurent D.

    Bonjour Chris,

    J’ai eu exactement les mêmes problèmes que toi.
    Le premier je l’ai résolu en mettant :
    private_key_path: %kernel.root_dir%/var/jwt/private.pem
    public_key_path: %kernel.root_dir%/var/jwt/public.pem

    Au début j’avais mis : app/var/jwt/public.pem

    Par contre je n’arrive toujours pas à m’authentifier via Authorization.
    Est-ce qu’il serait possible d’avoir un exemple de code côté front ?
    J’ai essayé avec jquery beforeSend (xhr.setRequestHeader) :
    Authorization : login:password
    Authorization : Basic login:password
    Authorization : Basic base64(login:password)

    De même une fois le token obtenu, j’ai renommé mon Bearer en Token :
    Authorization : Token valeurDuJwt

    Merci pour votre aide.

    • Article Author
  • Chris

    Me again. Please delete my posts. My bad! I think really there’s only two things one needs to be careful of:
    (i) if you generate the public/private keys as suggested in the readme docs, you need to make sure you populate the passphrase in config.yml

    (ii) you need to make sure you urlencode the passed token when you put in in the querystring.

    Thanks. Its a great piece of code!

    • Article Author
  • Nicolas

    Bonjour Laurent,

    Il y a deux étapes à distinguer : 1) la récupération d’un token et 2) l’utilisation de celui-ci.

    La récupération d’un token se fait au moyen d’une authentification standard identifiant / mot de passe via un POST de formulaire (XHR).

    Si l’authentification réussi, vous obtenez une réponse JSON contenant le JWT à renvoyer à chaque future requête au serveur en tant que Authorization Header.

    • Article Author
  • phil

    Tout comme Laurent, je pense avoir un soucis de configuration et/ou de compréhension de tout ca.

    J’utilise en front une app angular.js ou je gère le formulaire de login. Par contre j’ai un doute si je dois envoyer directement sur /login ou /login_check.

    De plus si je dois vérifier que pour chaque chargement de route, l’utilisateur n’a pas déclencher un timeout, quel en serait l’idée ?

    Merci pour votre aide

    • Article Author
  • Nicolas

    Salut Phil,

    Les identifiants doivent être envoyés en POST sur le check_path du form_login de ton firewall (/login_check par défaut et dans l’exemple du README).

    $http({
    method: ‘POST’,
    url: ‘/login_check’,
    headers: {‘Content-Type’: ‘application/x-www-form-urlencoded’},
    transformRequest: function (obj) {
    var str = [];
    for (var p in obj) {
    str.push(encodeURIComponent(p) + « = » + encodeURIComponent(obj[p]));
    }
    return str.join(« & »);
    },
    data: {
    username: ‘secret’,
    password: ‘secret’
    }
    });

    En ce qui concerne la gestion de l’expiration du token dans ton application AngularJS, tu peux te baser sur ce module : https://github.com/witoldsz/angular-http-auth qui fourni tout le nécessaire.

    • Article Author
  • axel

    Bonjour,

    j’ai un soucis, aucun token n’est envoyé j’ai l’erreur suivante : « net::ERR_CONNECTION_RESET » pourtant dans les logs symfony j’ai bien « User « admin » has been authenticated successfully ».
    Une idée?

    merci

    • Article Author
  • Nicolas

    Bonjour Axel,

    Ton erreur semble plus liée à ton navigateur qu’au bundle lui-même.
    As-tu testé la sandbox https://github.com/slashfan/LexikJWTAuthenticationBundleSandbox ?
    Clone le projet et suis les instructions d’installation, tu devrais te retrouver avec une application de test parfaitement fonctionnelle.

    • Article Author

Recevez nos articles