web-dev-qa-db-fra.com

Où placer une clé API: un en-tête HTTP personnalisé VS l'en-tête d'autorisation avec un schéma personnalisé

Je conçois une API REST utilisant l'autorisation/l'authentification via une clé API.

J'ai essayé de trouver le meilleur endroit pour cela et j'ai découvert que beaucoup de gens suggèrent d'utiliser un en-tête HTTP personnalisé tel que ProjectName-Api-Key, par exemple:

ProjectName-Api-Key: abcde

mais il est également possible et idéologiquement correct d'utiliser l'en-tête Authorization avec un schéma personnalisé, par exemple:

Authorization: ApiKey abcde

D'un autre côté, j'ai constaté qu'un schéma d'autorisation personnalisé peut être inattendu et non pris en charge par certains clients et conduit à un code personnalisé de toute façon, il est donc préférable d'utiliser un en-tête personnalisé car les clients n'ont aucune attente à ce sujet.

De quelle manière préféreriez-vous envoyer une clé API?

25
RomanG

Être cohérent

Certains diront que cela n'est pas nécessaire ( et il n'y a pas si longtemps, j'aurais accepté ) mais de nos jours, avec autant de protocoles d'authentification, si nous utilisons le Authorization entête pour passer un clé API , vaut également la peine d'informer type parce que clés API ne sont pas auto-descriptifs en soi 1.

Pourquoi est-ce que je pense que ça vaut le coup? Parce que de nos jours, la prise en charge de différents protocoles d'authentification ou d'autorisation est devenue un incontournable. Si nous prévoyons d'utiliser l'en-tête Authorization pour tous ces protocoles, nous devons rendre notre service d'authentification cohérent. La manière de communiquer le type de jeton que nous envoyons et le protocole d'autorisation à appliquer doit également figurer dans l'en-tête.

Authorization: Basic XXXX
Authorization: Digest XXXX
Authorization: Bearer XXXX
Authorization: ApiKey-v1 XXXX
Authorization: ApiKey-v2 XXXX

Auparavant, je m'en fichais, mais après avoir travaillé avec des clients mobiles ou des capteurs, dont les mises à jour n'étaient pas garanties, j'ai commencé à le faire. J'ai commencé à être plus cohérent dans la façon dont j'implémente la sécurité afin de pouvoir conserver une compatibilité descendante. Avec le type de jeton informé, je peux invalider les demandes d'un ensemble spécifique de clients (les plus anciens), ajouter de nouveaux schémas et différencier les anciens clients des nouveaux, modifier les validations d'authentification pour l'un ou l'autre schéma sans provoquer de modifications. Je peux également appliquer des règles spécifiques dans les passerelles API en fonction du schéma d'autorisation informé. Par exemple, je peux rediriger les anciens schémas vers des versions spécifiques de mes API Web qui sont déployées en dehors des principales.

Préoccupations

Les problèmes que j'ai rencontrés lors de la mise en œuvre de mes propres programmes sont similaires à celui commenté.

D'un autre côté, j'ai trouvé une considération qu'un schéma d'autorisation personnalisé peut être inattendu et non pris en charge par certains clients et conduit de toute façon au code personnalisé

Dites clients , dites bibliothèques, frameworks, proxy inverses . Un en-tête personnalisé peut être rejeté ou ignoré. Dans le pire des cas, il peut également entrer en collision.

Les avantages

Un avantage important est le cache. Les caches partagés ne mettront pas l'en-tête en cache (et c'est bien sûr bien sûr), sauf indication contraire.

Autorisation ou en-tête personnalisé?

D'après mon expérience, les deux me prennent presque le même travail et le temps de mise en œuvre, avec une légère différence avec plus de place pour la conception lorsque j'ai implémenté des en-têtes personnalisés. Cependant, plus de place pour la conception signifiait également plus de chances de trop compliquer les choses.

Techniquement, il pourrait y avoir très peu ou pas de différence entre les deux, mais j'ai trouvé que la cohérence est une propriété de toute solution que j'apprécie pour ce qu'elle m'apporte, la clarté et la compréhension. Dans mon cas, l'ajout de nouveaux schémas a été réduit pour ajouter 2 nouvelles abstractions (implémentées par la même classe concrète): TokenHandler et TokenValidator . Le gestionnaire vérifie uniquement si l'en-tête de demande Autorisation informe le schéma pris en charge. Le validateur est tout ce dont j'ai besoin pour valider le jeton. Fonctionnant au total à partir d'un seul filtre de demande, au lieu d'une chaîne de filtres ou d'une grosse boule de boue.


1: Je trouve cela réponse très clair concernant les clés API

16
Laiv