Accueil / Articles / Mappage du vocabulaire d’authentification : clés API, sessions, JWT, OAuth2, OIDC, SSO

Mappage du vocabulaire d’authentification : clés API, sessions, JWT, OAuth2, OIDC, SSO

Apprenez comment les clés API, les sessions, les JWT, OAuth2, OpenID Connect et SSO s’articulent en classant chacun d’eux sous une seule question : qui appelle, ou que peuvent-ils faire ?

2323 mots

Deux questions derrière chaque mécanisme d’authentification

  • Authentification demande qui êtes-vous ? Il s’agit du processus de vérification d’une identité, qu’elle appartienne à une personne, à un service backend ou à un appareil.
  • Autorisation demande que pouvez-vous faire ? Elle intervient après que l’identité a été établie et détermine quels ressources et actions sont accessibles.

HTTP encode déjà cette distinction dans ses codes d’état. Une réponse 401 Unauthorized signifie que l’expéditeur n’a pas prouvé son identité (malgré le nom trompeur, il s’agit bien d’une question d’authentification). Une réponse 403 Forbidden signifie que le serveur connaît précisément l’identité de l’expéditeur mais refuse néanmoins la demande. Si votre API renvoie 403 en cas d’absence de token ou 401 pour un utilisateur sans rôle, les clients ne savent pas s’ils doivent demander des identifiants ou afficher un message de « pas d’accès ».

l’authentification vs l’autorisation et leur emplacement dans le code.

Clés API : identifier un client, pas une personne

Les clés API représentent la forme la plus simple d’authentification du client. Le fournisseur vous délivre une chaîne unique que vous envoyez avec chaque requête, et le serveur la compare aux clés qu’il a enregistrées. De nombreuses API l’acceptent comme identifiant de porteur dans l’en-tête standard :

Authorization: Bearer your-api-key-here

D’autres fournisseurs utilisent un en-tête personnalisé tel que X-API-Key ; l’idée reste la même. La clé ne sert pas à décrire qui que ce soit. Il s’agit d’une valeur opaque, de sorte que le serveur doit la rechercher pour savoir quel compte effectue la demande. Elle ne possède aucune date d’expiration intégrée, sauf si vous en ajoutez une, et toute personne qui détient une clé divulguée a les mêmes droits d’accès que son propriétaire légitime. Cela fait de la rotation, de la définition des droits d’accès et du stockage sécurisé des clés votre responsabilité.

L’authentification HTTP Basic, qui envoie un nom d’utilisateur et un mot de passe codés en base64 dans une en-tête, existe toujours. La base64 est un encodage, pas un chiffrement ; par conséquent, l’authentification Basic n’est sécurisée que via TLS, et il est difficile de la justifier en dehors d’outils internes très simples. Les clés API constituent un choix plus courant et plus léger, idéal lorsque vous contrôlez les deux extrémités de la connexion ou lorsqu’un service facture et limite le nombre d’appels par compte.

Exemples typiques où l’on trouve des clés API :

  • API de modèles d’IA
  • Passerelles de paiement
  • API météorologiques et autres API de données
  • Appels entre services backend

Remarquez ce qui manque sur cette liste : les utilisateurs finaux se connectant à votre application. Une clé API identifie une application ou un compte qui effectue l’appel, et non la personne devant l’écran.

Séances : état côté serveur derrière un cookie

Longtemps avant que les JWT ne deviennent populaires, les sessions constituaient le moyen par défaut pour maintenir les utilisateurs connectés, et elles restent une option fiable pour les applications générées côté serveur.

Le processus est simple : l’utilisateur soumet ses identifiants, le serveur les vérifie et crée un enregistrement de session dans un stockage quelconque (mémoire, Redis ou base de données), puis la réponse inclut un cookie ne contenant que l’ID de session. Lors de chaque demande ultérieure, le navigateur envoie à nouveau ce cookie, et le serveur cherche cet ID pour retrouver la session ainsi que l’utilisateur y associé.

Cette architecture est basée sur un état, ce qui en fait également la force : le serveur détient l’information fiable, de sorte que déconnecter un utilisateur ou annuler une session compromise suffit à supprimer simplement l’enregistrement correspondant. Le cookie lui-même ne contient rien de sensible en dehors d’un identifiant aléatoire.

Le coût apparaît lorsque l’on effectue une mise à l’échelle horizontale. Si plusieurs serveurs gèrent le trafic, ils doivent tous accéder au même stockage de sessions ; sinon, un utilisateur connecté sur une instance apparaîtra anonyme sur l’autre. Une instance Redis partagée résout bien ce problème en pratique, mais c’est un composant de plus à déployer, à surveiller et à configurer correctement. De plus, un stockage de sessions mal configuré est le type de problème qui survient au pire moment possible lors d’une mise en production.

Les sessions restent un choix excellent pour :

  • Les applications web traditionnelles générées côté serveur
  • Les tableaux de bord administratifs
  • Les applications où la révocation immédiate est plus importante que l’absence d’état

JWT : autonome, signé et lisible

Un token Web JSON est un objet JSON signé contenant des informations telles qu’un identifiant d’utilisateur, des rôles et une date d’expiration. Il se compose de trois segments codés en base64url reliés par des points :

Header.Payload.Signature

Le en-tête indique l’algorithme de signature, la charge utile contient les affirmations, et la signature permet au serveur de confirmer que aucune des deux parties n’a été modifiée par quiconque sans la clé de signature. Comme les affirmations se trouvent à l’intérieur du jeton, un serveur peut authentifier une demande en vérifiant la signature et en lisant la charge utile, sans avoir recours à une recherche dans une base de données. C’est cette propriété qui fait que les JWT conviennent aux systèmes sans état et distribués.

Signé ne signifie pas secret

La méprise la plus courante est de penser qu’un JWT cache son contenu. Ce n’est pas le cas. Un JWT standard est signé, non chiffré, et quiconque le détient peut déchiffrer son chargement avec une simple opération base64. Ne mettez jamais de mots de passe, de données personnelles que vous ne voudriez pas montrer à l’utilisateur, ou de secrets internes dans les claims en supposant qu’ils restent privés. Lorsqu’un incident lié à un JWT se produit, cette supposition erronée en est souvent la cause. (Des jetons chiffrés existent bien selon la spécification JWE, mais ils constituent un format distinct et ne correspondent que rarement à ce qu’un tutoriel entend par « JWT ».)

Jetons d’accès et de renouvellement

Puisqu’un JWT reste valide jusqu’à son expiration, le schéma habituel associe deux jetons :

  • Jeton d’accès : à durée de vie courte, généralement de 15 minutes à une heure, et envoyé avec chaque demande API.
  • Jeton de renouvellement : à longue durée de vie, allant de quelques jours à plusieurs semaines, et utilisé uniquement pour obtenir un nouveau jeton d’accès sans demander à l’utilisateur de se connecter à nouveau.
  • Stockez le jeton de renouvellement dans un cookie HttpOnly plutôt que dans localStorage, où tout script injecté pourrait le lire. La courte durée de vie du jeton d’accès limite les conséquences d’une fuite, tandis que c’est le jeton de renouvellement qui permet d’intégrer la logique de révocation.

    Les JWT conviennent bien aux API, aux clients mobiles, aux applications single-page et aux services distribués. Ils n’ont pas rendu les sessions obsolètes ; ils échangent une révocation facile contre un étatless, et le choix approprié dépend de votre architecture. La comparaison des sessions et des JWT en tant que modèles d’authentification Node.js examine en détail cet équilibre.

    OAuth 2.0 : accès délégué, pas connexion

    OAuth 2.0 est le concept qui est le plus souvent mis dans le tiroir erroné. Il s’agit d’un cadre d’autorisation, et non d’un protocole d’authentification. Son rôle est de permettre à une application d’accéder aux ressources hébergées par un autre service au nom de l’utilisateur, sans que celui-ci ait à fournir son mot de passe.

    Dans le flux courant basé sur un code d’autorisation, votre application redirige l’utilisateur vers l’écran de consentement du fournisseur, qui demande quelque chose comme "Autoriser cette application à consulter vos fichiers de Google Drive ?". Si l’utilisateur accepte, le fournisseur redirige vers votre application avec un code d’autorisation à durée limitée. Votre backend échange ensuite ce code contre un jeton d’accès, avant d’appeler l’API du fournisseur à l’aide de ce dernier.

    Ce jeton d’accès représente l’autorisation d’accéder à certains ressources. Il ne constitue pas une indication sur l’identité de l’utilisateur, et la spécification OAuth2 ne définit pas son format ni n’exige que votre application puisse le lire. Considérer l’arrivée d’un jeton d’accès comme une preuve que l’utilisateur est connecté est l’erreur classique évoquée dans le scénario initial, et cela a entraîné de véritables vulnérabilités, par exemple lorsque un jeton émis pour une application est accepté comme preuve d’identité par une autre.

    OAuth2 a été conçu pour répondre à des questions telles que :

    • Cette application peut-elle lire les fichiers du Drive de l’utilisateur ?
    • Cette application peut-elle accéder aux répertoires de l’utilisateur ?

    Il n’a pas été conçu pour répondre à la question : qui est cet utilisateur ?

    OpenID Connect : la couche d’identité au-dessus d’OAuth2

    Si OAuth2 indique ce à quoi une application peut accéder, OpenID Connect ajoute l’information manquante concernant l’identité de la personne. OIDC est une couche d’identification légère construite sur OAuth2, qui réutilise ses mécanismes de redirection et d’échange de tokens. Lorsque vous cliquez sur « Se connecter avec Google », le processus en cours est basé sur OIDC, et non simplement sur OAuth2.

    Après que l’utilisateur s’est authentifié, un fournisseur OIDC renvoie deux tokens ayant des fonctions différentes :

    • token d’identité, qui est un JWT décrivant l’utilisateur : un identifiant unique et stable, contenant généralement des informations telles que le nom et l’adresse e-mail.
    • token d’accès, qui permet à votre application d’appeler des API au nom de l’utilisateur.

    Le jeton d’identité est ce qui authentifie l’utilisateur auprès de votre application. Le jeton d’accès est ce qui autorise les prochaines actions de votre application. Votre backend doit valider la signature, l’émetteur, le public cible et la date d’expiration du jeton d’identité avant de faire confiance à ses affirmations, et doit associer les comptes utilisateurs au identifiant sujet stable plutôt qu’à une adresse e-mail qui peut changer. Vu de cette manière, OAuth2 seul ne peut pas assurer la connexion ; OIDC la complète.

    SSO : une expérience, assurée par des protocoles

    Le Single Sign-On est souvent confondu avec les protocoles qui le mettent en œuvre. Le SSO est un modèle d’expérience utilisateur : s’authentifier une seule fois puis naviguer entre plusieurs systèmes sans devoir se reconnecter. Google en est l’exemple bien connu : on s’identifie une fois, et Gmail, Drive, Calendar ainsi que YouTube vous reconnaissent tous.

    Deux protocoles assurent la majeure partie du travail derrière le SSO :

    • SAML : Basé sur XML et mature, il domine les environnements d’entreprise tels que les portails corporatifs, les tableaux de bord CRM et les outils internes.
    • OpenID Connect : Basé sur JSON et JWT, il est plus récent et constitue la solution privilégiée pour les applications web et mobiles.

    SAML est connu pour être difficile à mettre en œuvre et à déboguer ; par conséquent, pour un nouveau système, OIDC représente généralement la voie la plus simple. SAML reste utile lorsque l’on doit s’intégrer à des fournisseurs d’identité d’entreprise qui ne proposent pas OIDC, et de nombreux de ces fournisseurs sont encore en usage.

    Lorsque quelqu’un vous demande d’« ajouter l’SSO », la première chose à vérifier est quel protocole utilise son fournisseur d’identité. Cette réponse détermine les bibliothèques, la configuration ainsi que les étapes de test à suivre.

    Choix du mécanisme

    En résumé, un guide de décision approximatif se présente comme suit :

    • Votre service est appelé par d’autres programmes, et non par des personnes : clés API, limitées dans leur portée et mises à jour régulièrement, ou identifiants de client OAuth2 si vous avez besoin de jetons périmés.
    • Une application générée côté serveur ou un panneau d’administration avec son propre système de connexion : sessions utilisant une cookie sécurisée HttpOnly.
    • API sans état, clients mobiles ou plusieurs services vérifiant le même utilisateur : jetons d’accès JWT accompagnés de jetons de renouvellement.
    • Votre application doit agir sur les données d’un utilisateur dans un autre service : OAuth 2.0.
    • Vous souhaitez que les utilisateurs se connectent avec un compte existant comme Google : OpenID Connect.
    • Les employés ont besoin d’un seul accès pour de nombreux outils internes ou SaaS : SSO via OIDC, ou SAML lorsque le fournisseur d’identité l’exige.

    Ces options se combinent. Un produit typique peut utiliser OIDC pour se connecter, émettre ensuite sa propre session ou un JWT, tout en conservant des tokens d’accès OAuth2 pour les intégrations avec des tiers.

    Questions fréquentes

    En pratique, en quoi l’authentification et l’autorisation diffèrent-elles ? L’authentification vérifie l’identité et échoue avec un code HTTP 401 ; l’autorisation vérifie les permissions et échoue avec un code 403. Il s’agit de étapes distinctes avec des codes d’erreur différents, et les fusionner crée de réels défauts de sécurité.

    Faut-il utiliser des JWT ou des sessions ? Les sessions sont idéales pour les applications générées côté serveur qui peuvent partager un stockage de sessions. Les JWT sont plus adaptés aux API sans état, aux clients mobiles et aux systèmes distribués. Prenez votre décision en fonction de votre architecture et de vos besoins de révocation, et non en fonction du fait que l’une des options semble plus moderne.

    L’OAuth2 sert-il à l’authentification ou à l’autorisation ? À l’autorisation. Il permet aux applications d’accéder à des ressources au nom d’un utilisateur sans confirmer qui est cet utilisateur. Pour l’identité, utilisez OpenID Connect, qui étend OAuth2 à cette fin précise.

    Points clés

    • Réglez chaque mécanisme en fonction d’une seule question : qui appelle ? ou que peuvent-ils faire ?
    • Les clés API identifient les applications clientes ; elles ne contiennent aucune information d’identité utilisateur et nécessitent une date d’expiration ainsi qu’un processus de rotation propre.
    • Les sessions conservent l’état sur le serveur, ce qui facilite la révocation mais exige un stockage partagé à grande échelle.
    • Les JWT sont signés, non chiffrés ; gardez les secrets hors du payload et les tokens de renouvellement hors de localStorage.
    • OAuth2 accorde un accès délégué ; OIDC ajoute le token d’identité qui permet réellement de connecter un utilisateur.
  • SSO est une expérience qui s’implémente à l’aide d’OIDC ou de SAML, en fonction du fournisseur d’identité.
  • La plupart des confusions dans ce domaine, y compris la confusion avec l’option « Se connecter avec Google » mentionnée au début, proviennent du mélange de ces deux concepts. Il faut séparer l’identité des permissions ; choisir parmi ces outils devient alors une question de correspondance entre chacun d’eux et le type de problème qu’il est conçu pour résoudre.