web-dev-qa-db-fra.com

REST Modèle de connexion à l'API

Je crée un REST api, en suivant de près les suggestions des apigées, en utilisant des noms non verbes, la version de l'api cuite dans l'URL, deux chemins d'api par collection, GET POST PUT DELETE, etc.

Je suis en train de travailler sur le système de connexion, mais je ne suis pas sûr de la manière correcte REST de connecter les utilisateurs. Je ne travaille pas sur la sécurité à ce stade, juste le modèle ou le flux de connexion. (Plus tard, nous ajouterons 2 étapes oAuth, avec un HMAC, etc.)

Options possibles

  • Un POST à quelque chose comme https://api...com/v1/login.json
  • UN PUT à quelque chose comme https://api...com/v1/users.json
  • Quelque chose que je n'ai pas pensé de ...

Quel est le bon style REST pour connecter les utilisateurs?

174
Scott Roepnack

Conception basée sur les principes de l'architecture Web moderne de Roy T. Fielding et Richard N. Taylor , c'est-à-dire une séquence de travaux de toute la terminologie REST, contient la définition de l'interaction client-serveur:

Toutes les interactions REST sont sans état . C'est-à-dire que chaque requête contient toutes les informations nécessaires à la compréhension de la requête par un connecteur, indépendamment de toutes les requêtes qui l'ont éventuellement précédée .

Cette restriction remplit quatre fonctions, les première et troisième sont importantes dans ce cas particulier:

  • 1st: it supprime la nécessité pour les connecteurs de conserver l'état de l'application entre les requêtes , réduisant ainsi la consommation de ressources physiques et améliorant l'évolutivité;
  • 3rd: il permet à un intermédiaire de visualiser et comprendre une requête de manière isolée , ce qui peut être nécessaire lorsque les services sont réorganisés de manière dynamique;

Et maintenant, revenons à votre dossier de sécurité. Chaque demande doit contenir toutes les informations requises, et l'autorisation/authentification ne fait pas exception. Comment y parvenir? Envoyez littéralement toutes les informations requises par fil à chaque demande.

Un des exemples expliquant comment obtenir ceci est le code d'authentification de message basé sur un hachage ou HMAC . En pratique, cela signifie l’ajout d’un code de hachage du message actuel à chaque requête. Code de hachage calculé parfonction de hachage cryptographiqueen combinaison avec unclé cryptographique secrète.La fonction de hachage cryptographiqueest prédéfinie ou fait partie decode à la demandeREST conception (par exemple JavaScript).La clé cryptographique secrètedoit être fournie par le serveur au client en tant que ressource, et le client l'utilise pour calculer le code de hachage pour chaque demande.

Il existe de nombreux exemples d'implémentations HMAC, mais j'aimerais que vous accordiez une attention particulière aux trois suivants:

Comment ça marche en pratique

Si le client connaît la clé secrète, il est alors prêt à fonctionner avec des ressources. Sinon, il sera temporairement redirigé (code de statut 307 Redirect) pour autoriser et obtenir une clé secrète, puis redirigé vers la ressource d'origine. Dans ce cas, il y ail n'est pas nécessaire de savoir à l'avance (c'est-à-dire un code quelconque) quel est l'URL autorisant le client est, et il est possible d'ajuster ce schéma avec le temps.

J'espère que cela vous aidera à trouver la solution adéquate!

131
Akim

TL; DR La connexion pour chaque demande n'est pas un composant requis pour implémenter la sécurité de l'API, mais l'authentification.

Il est difficile de répondre à votre question sur la connexion sans parler de la sécurité en général. Avec certains schémas d'authentification, il n'y a pas de login traditionnel.

REST ne dicte aucune règle de sécurité, mais l'implémentation la plus courante est en pratique OAuth avec une authentification à 3 voies (comme vous l'avez mentionné dans votre question). Il n'y a pas de connexion en soi, du moins pas avec chaque demande d'API. Avec l'authentification à 3 voies, vous utilisez simplement des jetons.

  1. L'utilisateur approuve le client API et accorde la permission de faire des demandes sous la forme d'un jeton de longue durée
  2. Le client Api obtient un jeton de courte durée en utilisant celui qui a une longue durée de vie.
  3. Le client Api envoie le jeton éphémère à chaque demande.

Ce schéma donne à l'utilisateur la possibilité de révoquer l'accès à tout moment. Pratiquement toutes les API RESTful disponibles publiquement que j'ai vues utilisent OAuth pour implémenter cela.

Je ne pense tout simplement pas que vous devriez définir votre problème (et votre question) en termes de connexion, mais plutôt penser à la sécurisation de l'API en général.

Pour plus d'informations sur l'authentification des API REST en général, vous pouvez consulter les ressources suivantes:

41
Slavo

Une grande partie de la philosophie REST consiste à exploiter autant de fonctions standard du protocole HTTP que possible lors de la conception de votre API. En appliquant cette philosophie à l'authentification, le client et le serveur utiliseraient les fonctionnalités d'authentification HTTP standard de l'API.

Les écrans de connexion sont parfaits pour les cas d'utilisation par des utilisateurs humains: visitez un écran de connexion, indiquez un utilisateur/mot de passe, définissez un cookie, le client fournit ce cookie dans toutes les demandes futures. On ne peut s’attendre à ce que les humains utilisant des navigateurs Web fournissent un identifiant utilisateur et un mot de passe avec chaque requête HTTP individuelle.

Toutefois, pour une API REST, un écran de connexion et les cookies de session ne sont pas strictement nécessaires, car chaque demande peut inclure des informations d'identification sans impacter un utilisateur humain. et si le client ne coopère à aucun moment, une réponse 401 "non autorisée" peut être donnée. RFC 2617 décrit le support d'authentification dans HTTP.

TLS (HTTPS) serait également une option et permettrait l'authentification du client auprès du serveur (et inversement) dans chaque demande en vérifiant la clé publique de l'autre partie. De plus, cela sécurise le canal pour un bonus. Bien entendu, un échange de paire de clés avant la communication est nécessaire pour ce faire. (Remarque: il s'agit spécifiquement d'identifier/authentifier l'utilisateur avec TLS. Sécuriser le canal à l'aide de TLS/Diffie-Hellman est toujours une bonne idée, même si vous n'identifiez pas l'utilisateur avec sa clé publique.)

Un exemple: supposons qu'un jeton OAuth constitue vos identifiants de connexion complets. Une fois que le client dispose du jeton OAuth, il peut être indiqué comme identifiant d'utilisateur dans l'authentification HTTP standard avec chaque demande. Le serveur peut vérifier le jeton lors de la première utilisation et mettre en cache le résultat de la vérification avec une durée de vie renouvelée à chaque demande. Toute demande nécessitant une authentification retourne 401 si elle n’est pas fournie.

24
wberry