L'utilisation de sessions dans une API RESTful viole-t-elle vraiment RESTfulness? J'ai vu beaucoup d'opinions dans les deux sens, mais je ne suis pas convaincu que les sessions soient RESTless . De mon point de vue:
- l'authentification n'est pas interdite pour RESTfulness (sinon il y aurait peu d'utilité dans les services RESTful)
- l'authentification se fait en envoyant un jeton d'authentification dans la demande, généralement l'en-tête
- ce jeton d'authentification doit être obtenu d'une manière ou d'une autre et peut être révoqué, auquel cas il doit être renouvelé
- le jeton d'authentification doit être validé par le serveur (sinon ce ne serait pas l'authentification)
Alors, comment les sessions violent-elles cela?
- côté client, les sessions sont réalisées à l'aide de cookies
- les cookies sont simplement un en-tête HTTP supplémentaire
- un cookie de session peut être obtenu et révoqué à tout moment
- les cookies de session peuvent avoir une durée de vie infinie si besoin est
- l'ID de session (jeton d'authentification) est validé côté serveur
En tant que tel, pour le client, un cookie de session est exactement le même que tout autre mécanisme d'authentification basé sur un en-tête HTTP, sauf qu'il utilise l'en- Cookie
tête à la place du Authorization
ou d'un autre en-tête propriétaire. S'il n'y avait pas de session attachée à la valeur du cookie côté serveur, pourquoi cela ferait-il une différence? L'implémentation côté serveur n'a pas besoin de concerner le client tant que le serveur se comporte RESTful. En tant que tels, les cookies en eux-mêmes ne devraient pas rendre une API RESTless , et les sessions sont simplement des cookies pour le client.
Mes hypothèses sont-elles fausses? Qu'est-ce qui rend les cookies de session RESTless ?
la source
Réponses:
Définissons d'abord quelques termes:
Reposant:
selon wikipedia .
contrainte sans état:
selon la thèse de Fielding .
Les sessions côté serveur violent donc la contrainte sans état de REST, et donc RESTfulness.
Par les cookies de session, vous stockez l'état du client sur le serveur et votre demande a donc un contexte. Essayons d'ajouter un équilibreur de charge et une autre instance de service à votre système. Dans ce cas, vous devez partager les sessions entre les instances de service. Il est difficile de maintenir et d'étendre un tel système, il évolue donc mal ...
À mon avis, il n'y a rien de mal avec les cookies. La technologie des cookies est un mécanisme de stockage côté client dans lequel les données stockées sont jointes automatiquement aux en-têtes de cookies par chaque demande. Je ne connais pas de contrainte REST qui a un problème avec ce type de technologie. Il n'y a donc pas de problème avec la technologie elle-même, le problème est avec son utilisation. Fielding a écrit une sous-section expliquant pourquoi il pense que les cookies HTTP sont mauvais.
Votre point de vue était assez solide. Le seul problème était avec le concept de création de jeton d'authentification sur le serveur. Vous n'avez pas besoin de cette partie. Ce dont vous avez besoin est de stocker le nom d'utilisateur et le mot de passe sur le client et de l'envoyer avec chaque demande. Pour ce faire, vous n'avez pas besoin de plus que l'authentification de base HTTP et une connexion chiffrée:
Vous avez probablement besoin d'un cache d'authentification en mémoire côté serveur pour accélérer les choses, car vous devez authentifier chaque demande.
Maintenant, cela fonctionne assez bien pour les clients de confiance écrits par vous, mais qu'en est-il des clients tiers? Ils ne peuvent pas avoir le nom d'utilisateur et le mot de passe et toutes les autorisations des utilisateurs. Vous devez donc stocker séparément les autorisations qu'un client tiers peut avoir par un utilisateur spécifique. Ainsi, les développeurs de clients peuvent enregistrer leurs clients tiers et obtenir une clé API unique et les utilisateurs peuvent autoriser les clients tiers à accéder à une partie de leurs autorisations. Comme lire le nom et l'adresse e-mail, ou lister leurs amis, etc ... Après avoir autorisé un client tiers, le serveur générera un jeton d'accès. Ces jetons d'accès peuvent être utilisés par le client tiers pour accéder aux autorisations accordées par l'utilisateur, comme suit:
Ainsi, le client tiers peut obtenir le jeton d'accès d'un client de confiance (ou directement de l'utilisateur). Après cela, il peut envoyer une demande valide avec la clé API et le jeton d'accès. Il s'agit du mécanisme d'authentification tiers le plus basique. Vous pouvez en savoir plus sur les détails d'implémentation dans la documentation de chaque système d'authentification tiers, par exemple OAuth. Bien sûr, cela peut être plus complexe et plus sécurisé, par exemple, vous pouvez signer les détails de chaque demande côté serveur et envoyer la signature avec la demande, etc. La solution réelle dépend des besoins de votre application.
la source
Tout d'abord, REST n'est pas une religion et ne doit pas être abordé en tant que tel. Bien qu'il existe des avantages aux services RESTful, vous ne devez suivre les principes de REST que dans la mesure où ils ont un sens pour votre application.
Cela dit, l'authentification et l'état côté client ne violent pas les principes REST. Alors que REST requiert que les transitions d'état soient sans état, cela fait référence au serveur lui-même. Au cœur, tout REST concerne les documents. L'idée derrière l'apatridie est que le SERVEUR est apatride, pas les clients. Tout client émettant une demande identique (mêmes en-têtes, cookies, URI, etc.) doit être amené au même endroit dans l'application. Si le site Web stockait l'emplacement actuel de l'utilisateur et gérait la navigation en mettant à jour cette variable de navigation côté serveur, alors REST serait violé. Un autre client avec des informations de demande identiques serait transféré vers un emplacement différent en fonction de l'état côté serveur.
Les services Web de Google sont un exemple fantastique d'un système RESTful. Ils nécessitent un en-tête d'authentification avec la clé d'authentification de l'utilisateur à transmettre à chaque demande. Cela viole légèrement les principes REST, car le serveur suit l'état de la clé d'authentification. L'état de cette clé doit être conservé et elle a une sorte de date / heure d'expiration après laquelle elle n'accorde plus l'accès. Cependant, comme je l'ai mentionné en haut de mon article, des sacrifices doivent être consentis pour permettre à une application de fonctionner réellement. Cela dit, les jetons d'authentification doivent être stockés de manière à permettre à tous les clients possibles de continuer à accorder l'accès pendant leurs périodes de validité. Si un serveur gère l'état de la clé d'authentification au point qu'un autre serveur à charge équilibrée ne peut pas prendre en charge les demandes basées sur cette clé, vous avez commencé à vraiment violer les principes de REST. Les services de Google garantissent que, à tout moment, vous pouvez prendre un jeton d'authentification que vous utilisiez sur votre téléphone contre le serveur d'équilibrage de charge A et accéder au serveur d'équilibrage de charge B depuis votre bureau et avoir toujours accès au système et être dirigé vers les mêmes ressources si les demandes étaient identiques.
En résumé, vous devez vous assurer que vos jetons d'authentification sont validés par rapport à un magasin de sauvegarde quelconque (base de données, cache, etc.) pour vous assurer de conserver autant de propriétés REST que possible.
J'espère que tout cela a du sens. Vous devriez également consulter la section Contraintes de l'article de wikipedia sur le transfert d'état représentatif si vous ne l'avez pas déjà fait. Elle est particulièrement éclairante en ce qui concerne les arguments avancés par REST et pourquoi.
la source
Les cookies ne sont pas destinés à l'authentification. Pourquoi réinventer une roue? HTTP a des mécanismes d'authentification bien conçus. Si nous utilisons des cookies, nous n'utilisons HTTP que comme protocole de transport, donc nous devons créer notre propre système de signalisation, par exemple, pour dire aux utilisateurs qu'ils ont fourni une mauvaise authentification (utiliser HTTP 401 serait incorrect car nous ne le ferions probablement pas fournir
Www-Authenticate
à un client, comme les spécifications HTTP l'exigent :)). Il convient également de noter que ceSet-Cookie
n'est qu'une recommandation pour le client. Son contenu peut être ou non enregistré (par exemple, si les cookies sont désactivés), tandis que l'en-Authorization
tête est envoyé automatiquement à chaque demande.Un autre point est que, pour obtenir un cookie d'autorisation, vous voudrez probablement fournir vos informations d'identification quelque part en premier? Si oui, ne serait-ce pas RESTless? Exemple simple:
GET /a
sans cookiePOST /auth
Set-Cookie
GET /a
avec un cookie. MaisGET /a
se comporte-t-il idempotamment dans ce cas?Pour résumer cela, je crois que si nous accédons à une ressource et que nous devons nous authentifier, nous devons nous authentifier sur cette même ressource , pas ailleurs.
la source
Authorization: Basic
ouDigest
. Si vous voulez faire quelque chose de plus avancé que l'authentification de base ou d'authentification (et vous devriez) dans un contexte de navigateur, alors vous allez avoir besoin d'autre chose que l'en-Authorization
tête.GET /a
sans cookie et avec cookie sont clairement deux demandes différentes , et il est acceptable qu'ils se comportent différemment.GET /a
avec l'en-tête d'authentification est également le même queGET /a
sans l'en-tête d'authentification, ce qui le rend également inutilisable pour REST. Si vous allez traiter un en-tête http différemment d'un autre, vous allez au moins y remédier.En fait, RESTfulness s'applique uniquement aux RESSOURCES, comme indiqué par un identificateur de ressource universel. Donc, même parler de choses comme les en-têtes, les cookies, etc. en ce qui concerne REST n'est pas vraiment approprié. REST peut fonctionner sur n'importe quel protocole, même s'il se fait régulièrement via HTTP.
Le principal déterminant est le suivant: si vous envoyez un appel REST, qui est un URI, puis une fois que l'appel réussit vers le serveur, cet URI renvoie le même contenu, en supposant qu'aucune transition n'a été effectuée (PUT, POST, DELETE) ? Ce test exclurait les erreurs ou les demandes d'authentification renvoyées, car dans ce cas, la demande n'a pas encore été envoyée au serveur, c'est-à-dire la servlet ou l'application qui renverra le document correspondant à l'URI donné.
De même, dans le cas d'un POST ou PUT, pouvez-vous envoyer un URI / une charge utile donné, et quel que soit le nombre de fois que vous envoyez le message, il mettra toujours à jour les mêmes données, de sorte que les GET ultérieurs renvoient un résultat cohérent?
REST concerne les données d'application, pas les informations de bas niveau requises pour transférer ces données.
Dans le billet de blog suivant, Roy Fielding a donné un bon résumé de toute l'idée REST:
http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841
"Un système RESTful progresse d'un état stationnaire à l'autre, et chacun de ces états stationnaires est à la fois un état de départ potentiel et un état final potentiel. C'est-à-dire qu'un système RESTful est un nombre inconnu de composants obéissant à un ensemble simple de des règles telles qu'elles sont toujours soit à REST, soit en transition d'un état RESTful à un autre état RESTful. Chaque état peut être complètement compris par la ou les représentations qu'il contient et l'ensemble des transitions qu'il fournit, les transitions étant limitées à un uniforme ensemble d’actions à comprendre. Le système peut être un diagramme d’états complexe, mais chaque agent utilisateur ne peut voir qu’un seul état à la fois (l’état stationnaire actuel) et donc chaque état est simple et peut être analysé indépendamment. l'utilisateur, OTOH, peut créer ses propres transitions à tout moment (par exemple, saisir une URL, sélectionner un signet,ouvrir un éditeur, etc.). "
En ce qui concerne la question de l'authentification, qu'elle soit effectuée via des cookies ou des en-têtes, tant que les informations ne font pas partie de la charge utile URI et POST, cela n'a vraiment rien à voir avec REST. Donc, en ce qui concerne les apatrides, nous parlons uniquement des données d'application.
Par exemple, lorsque l'utilisateur saisit des données dans un écran GUI, le client garde une trace des champs qui ont été saisis, qui ne l'ont pas été, des champs obligatoires manquants, etc. par le serveur. Ce qui est envoyé au serveur, c'est l'ensemble complet des champs qui doivent être modifiés dans la ressource IDENTIFIED (par l'URI), de sorte qu'une transition se produit dans cette ressource d'un état RESTful à un autre.
Ainsi, le client garde une trace de ce que fait l'utilisateur et envoie uniquement des transitions d'état logiquement complètes au serveur.
la source
La transaction HTTP, authentification d'accès de base, ne convient pas pour RBAC, car l'authentification d'accès de base utilise le nom d'utilisateur chiffré: mot de passe à chaque fois pour identifier, tandis que ce qui est nécessaire dans RBAC est le rôle que l'utilisateur souhaite utiliser pour un appel spécifique. RBAC ne valide pas les autorisations sur le nom d'utilisateur, mais sur les rôles.
Vous pouvez essayer de concaténer comme ceci: usernameRole: password, mais c'est une mauvaise pratique, et c'est aussi inefficace car lorsqu'un utilisateur a plus de rôles, le moteur d'authentification devra tester tous les rôles en concaténation, et que chaque appel à nouveau. Cela détruirait l'un des plus grands avantages techniques de RBAC, à savoir un test d'autorisation très rapide.
Ce problème ne peut donc pas être résolu à l'aide de l'authentification d'accès de base.
Pour résoudre ce problème, le maintien de session est nécessaire, et cela semble, selon certaines réponses, en contradiction avec REST.
C'est ce que j'aime dans la réponse selon laquelle REST ne doit pas être traité comme une religion. Dans les cas commerciaux complexes, dans les soins de santé, par exemple, le RBAC est absolument courant et nécessaire. Et il serait dommage qu'ils ne soient pas autorisés à utiliser REST car tous les concepteurs d'outils REST traiteraient REST comme une religion.
Pour moi, il n'y a pas beaucoup de façons de maintenir une session sur HTTP. On peut utiliser des cookies, avec un sessionId, ou un en-tête avec un sessionId.
Si quelqu'un a une autre idée, je serai heureuse de l'entendre.
la source
je pense que le jeton doit inclure toutes les informations nécessaires encodées à l'intérieur, ce qui rend l'authentification en validant le jeton et en décodant les informations https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/
la source
la source