Passer au contenu principal
Dans cette section, nous verrons comment implémenter une API dans notre cas d’utilisation.
Par souci de simplicité, notre implémentation se concentrera uniquement sur l’authentification et l’autorisation. Comme vous le verrez dans les exemples, l’entrée de feuille de temps fournie à l’API sera codée en dur, et l’API ne la conservera pas. Elle se contentera simplement de renvoyer une partie des informations.

Définir les points de terminaison de l’API

Nous devons d’abord définir les points de terminaison de notre API.

Qu’est-ce qu’un point de terminaison d’API ?

Un point de terminaison d’API est une URL unique qui représente un objet. Pour interagir avec cet objet, vous devez faire pointer votre application vers son URL. Par exemple, si vous aviez une API capable de renvoyer des commandes ou des clients, vous pourriez configurer deux points de terminaison : /orders et /customers. Votre application interagirait avec ces points de terminaison au moyen de différentes méthodes HTTP ; par exemple, POST /orders pourrait créer une nouvelle commande, tandis que GET /orders pourrait récupérer l’ensemble de données d’une ou de plusieurs commandes.
Pour cette implémentation, nous ne définirons que 2 points de terminaison : un pour récupérer la liste de toutes les feuilles de temps d’un employé, et un autre pour permettre à un employé de créer une nouvelle entrée de feuille de temps. Une requête HTTP GET vers le point de terminaison /timesheets permettra à un utilisateur de récupérer ses feuilles de temps, et une requête HTTP POST vers le point de terminaison /timesheets lui permettra d’ajouter une nouvelle feuille de temps. Voir l’implémentation en Node.js.

Sécuriser les points de terminaison

Lorsqu’une API reçoit une requête contenant un jeton du porteur dans l’en-tête, la première chose à faire est de valider le jeton. Ce processus comporte une série d’étapes, et si l’une d’elles échoue, la requête doit être rejetée avec le message d’erreur Missing or invalid token à l’intention de l’application appelante. Les validations que l’API doit effectuer sont :
  • Vérifier que le est bien formé
  • Vérifier la signature
  • Valider les revendications standard
JWT.io fournit une liste de bibliothèques capables d’effectuer l’essentiel du travail pour vous : analyser le JWT, vérifier la signature et les revendications.
Le processus de validation comprend aussi la vérification des autorisations de l’application (scopes), mais nous traiterons ce point séparément dans le paragraphe suivant de ce document. Pour en savoir plus sur la validation des jetons d’accès, consultez Valider les jetons d’accès. Consultez l’implémentation dans Node.js.

Vérifier les autorisations de l’application

À ce stade, nous avons vérifié que le JWT est valide. La dernière étape consiste à vérifier que l’application dispose des autorisations requises pour accéder aux ressources protégées. Pour ce faire, l’API doit vérifier les scopes du JWT décodé. Cette revendication fait partie du payload et se présente sous la forme d’une liste de chaînes séparées par des espaces. Voir l’implémentation dans Node.js.

Déterminer l’identité de l’utilisateur

Pour les deux points de terminaison (récupération de la liste des feuilles de temps et ajout d’une nouvelle feuille de temps), nous devrons déterminer l’identité de l’utilisateur. Pour récupérer la liste des feuilles de temps, cela permet de s’assurer que nous renvoyons uniquement les feuilles de temps appartenant à l’utilisateur à l’origine de la demande. Pour ajouter une nouvelle feuille de temps, cela permet de s’assurer que la feuille de temps est associée à l’utilisateur à l’origine de la demande. L’une des revendications JWT standard est la revendication sub, qui identifie l’entité principale visée par la revendication. Dans le cas du flux d’octroi implicite, cette revendication contiendra l’identité de l’utilisateur, c’est-à-dire l’identifiant unique de l’utilisateur Auth0. Vous pouvez l’utiliser pour associer à un utilisateur particulier toute information stockée dans des systèmes externes. Vous pouvez également utiliser une revendication personnalisée pour ajouter un autre attribut de l’utilisateur — comme son adresse de courriel — au Jeton d’accès et vous en servir pour identifier l’utilisateur de façon unique. Consultez l’implémentation dans Node.js.

Implémenter la SPA

Dans cette section, nous verrons comment mettre en œuvre une SPA dans notre scénario.

Autoriser l’utilisateur

Pour autoriser l’utilisateur, nous allons utiliser la bibliothèque auth0.js. Vous pouvez initialiser une nouvelle instance de l’application Auth0 comme suit : Vous devez fournir les valeurs de configuration suivantes :
  • clientID: La valeur de votre Auth0. Vous pouvez la récupérer dans les paramètres de votre application, dans le Auth0 Dashboard.
  • domain: La valeur de votre Domaine Auth0. Vous pouvez la récupérer dans les paramètres de votre application, dans le Auth0 Dashboard.
  • responseType: Indique le flux d’authentification à utiliser. Pour une SPA qui utilise le flux implicite, cette valeur doit être définie sur token id_token. La partie token déclenche le renvoi d’un jeton d’accès dans le fragment d’URL, tandis que la partie id_token déclenche aussi le renvoi d’un .
  • : La valeur de l’identifiant de votre API. Vous pouvez la récupérer dans les paramètres de votre API, dans le Auth0 Dashboard.
  • redirectUri: L’URL vers laquelle Auth0 doit rediriger l’utilisateur une fois l’authentification terminée.
  • scope: Les scopes qui déterminent les informations renvoyées dans l’ID Token et le jeton d’accès. Un scope de openid profile renverra toutes les informations du profil utilisateur dans l’ID Token. Vous devez aussi demander les scopes requis pour appeler l’API, dans ce cas les scopes read:timesheets create:timesheets. Cela garantira que le jeton d’accès contient ces scopes.
Pour lancer le flux d’authentification, vous pouvez appeler la méthode authorize() :
auth0.authorize();
Après l’authentification, Auth0 redirigera l’utilisateur vers le redirectUri que vous avez spécifié lors de la configuration de la nouvelle instance de l’application Auth0. À ce stade, vous devrez appeler la méthode parseHash(), qui analyse un fragment de hash d’URL pour extraire le résultat d’une réponse d’authentification d’Auth0. Le contenu de l’objet authResult renvoyé par parseHash dépend des paramètres d’authentification utilisés. Il peut inclure les éléments suivants :
  • idToken : un JWT ID Token contenant des informations de profil utilisateur
  • accessToken : un jeton d’accès pour l’API spécifiée par audience.
  • expiresIn : une chaîne de caractères contenant la durée d’expiration (en secondes) du jeton d’accès.
Déterminez où il est préférable de stocker les jetons. Si votre application monopage a un serveur backend, les jetons doivent être gérés côté serveur à l’aide du flux de code d’autorisation ou du flux de code d’autorisation avec Proof Key for Code Exchange (PKCE). Si vous avez une application monopage (SPA) sans serveur backend correspondant, votre SPA doit demander de nouveaux jetons à la connexion et les stocker en mémoire, sans persistance. Pour effectuer des appels d’API, votre SPA utilisera ensuite la copie du jeton conservée en mémoire. Pour obtenir un exemple de gestion des sessions dans les SPA, consultez la section Traiter les jetons d’authentification du guide de démarrage rapide pour les applications monopages JavaScript. Voir l’implémentation en Angular 2.

Obtenir le profil utilisateur

Extraire les informations du jeton

Cette section montre comment récupérer les informations de l’utilisateur à l’aide du Jeton d’accès et du point de terminaison /userinfo. Pour éviter cet appel d’API, vous pouvez simplement décoder l’ID Token à l’aide d’une bibliothèque (assurez-vous de le valider d’abord). Si vous avez besoin de renseignements supplémentaires sur l’utilisateur, envisagez d’utiliser notre Management API depuis votre serveur principal.
La méthode client.userInfo peut être appelée en lui passant le authResult.accessToken renvoyé afin de récupérer les informations du profil de l’utilisateur. Elle enverra une requête au point de terminaison /userinfo et renverra l’objet user, qui contient les informations de l’utilisateur, comme dans l’exemple ci-dessous :
{
    "email_verified": "false",
    "email": "test@example.com",
    "clientID": "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH",
    "updated_at": "2017-02-07T20:50:33.563Z",
    "name": "tester9@example.com",
    "picture": "https://gravatar.com/avatar/example.png",
    "user_id": "auth0|123456789012345678901234",
    "nickname": "tester9",
    "created_at": "2017-01-20T20:06:05.008Z",
    "sub": "auth0|123456789012345678901234"
}
Vous pouvez accéder à n’importe quelle propriété dans la fonction callback passée lors de l’appel à la fonction userInfo :
const accessToken = authResult.accessToken;

auth0.client.userInfo(accessToken, (err, profile) => {
  if (profile) {
    // Obtenir le surnom et l'image de profil de l'utilisateur
    var nickname = profile.nickname;
    var picture = profile.picture;
  }
});
Consultez l’implémentation dans Angular 2.

Afficher des éléments d’interface conditionnellement selon le scope

Selon le scope de l’utilisateur, vous pouvez afficher ou masquer certains éléments d’interface. Pour déterminer le scope accordé à un utilisateur, vous devez stocker le scope initialement demandé pendant le processus d’autorisation. Lorsqu’un utilisateur est autorisé, le scope est également renvoyé dans authResult. Si le scope dans authResult est vide, cela signifie que tous les scopes demandés ont été accordés. Si le scope dans authResult n’est pas vide, cela signifie qu’un ensemble différent de scopes a été accordé, et vous devez utiliser ceux de authResult.scope. Consultez l’implémentation dans Angular 2.

Appeler l’API

Pour accéder aux ressources sécurisées de votre API, le Jeton d’accès de l’utilisateur authentifié doit être inclus dans les requêtes qui lui sont adressées. Pour ce faire, envoyez le Jeton d’accès dans un en-tête Authorization à l’aide du schéma Bearer. Voir l’implémentation dans Angular 2.

Renouveler le Jeton d’accès

Par mesure de sécurité, il est recommandé de limiter la durée de vie du Jeton d’accès d’un utilisateur. Lorsque vous créez une API dans le , la durée de vie par défaut est de 7200 secondes (2 heures), mais elle peut être configurée pour chaque API. Une fois expiré, un Jeton d’accès ne peut plus être utilisé pour accéder à une API. Pour y accéder de nouveau, il faut obtenir un nouveau Jeton d’accès. Pour obtenir un nouveau Jeton d’accès, vous pouvez répéter le flux d’authentification utilisé pour obtenir le Jeton d’accès initial. Dans une SPA, ce n’est pas idéal, car vous ne voudrez peut-être pas rediriger l’utilisateur loin de sa tâche en cours pour qu’il termine de nouveau le flux d’authentification. Dans ce genre de cas, vous pouvez utiliser l’authentification silencieuse. L’authentification silencieuse vous permet d’exécuter un flux d’authentification dans lequel Auth0 ne renvoie que des redirections, jamais une page de connexion. Cela exige toutefois que l’utilisateur soit déjà connecté au moyen de l’authentification unique (SSO). Consultez l’implémentation dans Angular 2.