Les sessions violent-elles vraiment le RESTfulness?

Est-ce que l’utilisation de sessions dans une API RESTful viole vraiment le RESTfulness? J’ai vu beaucoup d’opinions aller dans les deux sens, mais je ne suis pas convaincu que les sessions sont RESTless . De mon sharepoint vue:

  • l’authentification n’est pas interdite pour RESTfulness (sinon il y aurait peu d’utilisation dans les services RESTful)
  • l’authentification se fait en envoyant un jeton d’authentification dans la requête, 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 une 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 nécessaire
  • l’identifiant de session (jeton d’authentification) est validé côté serveur

En tant que tel, un cookie de session est exactement identique à tout autre mécanisme d’authentification basé sur un en-tête HTTP, sauf qu’il utilise l’en-tête Cookie au lieu de l’en-tête Authorization ou d’un autre en-tête propriétaire. Si aucune session n’était associée à la valeur du serveur 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.

Est-ce que mes hypothèses sont fausses? Qu’est-ce qui rend les cookies de session RESTless ?

Tout d’abord, définissons quelques termes:

  • Reposant:

    On peut caractériser les applications conformes aux contraintes REST décrites dans cette section comme “RESTful”. [15] Si un service ne respecte aucune des contraintes requirejses, il ne peut pas être considéré comme RESTful.

    selon wikipedia .

  • contrainte sans état:

    Nous ajoutons ensuite une contrainte à l’interaction client-serveur: la communication doit être de nature sans état, comme dans le style client-stateless-server (CSS) de la section 3.4.3 (Figure 5-3), de sorte que chaque requête du client à Le serveur doit contenir toutes les informations nécessaires pour comprendre la demande et ne peut tirer parti d’aucun contexte stocké sur le serveur. L’état de la session est donc entièrement conservé sur le client.

    selon le mémoire de Fielding .

Les sessions côté serveur violent donc la contrainte sans état de REST et donc RESTfulness.

En tant que tel, un cookie de session est exactement identique à tout autre mécanisme d’authentification basé sur un en-tête HTTP, sauf qu’il utilise l’en-tête Cookie au lieu de l’en-tête Authorization ou d’un autre en-tête propriétaire.

Par cookies de session, vous stockez l’état du client sur le serveur et votre demande a donc un contexte. Essayons d’append 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, de sorte qu’il échoue 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 automatiquement attachées aux en-têtes de cookies à chaque demande. Je ne connais pas de contrainte REST qui pose problème avec ce type de technologie. Donc, il n’y a pas de problème avec la technologie elle-même, le problème est lié à son utilisation. Fielding a écrit une sous-section expliquant pourquoi il pense que les cookies HTTP sont mauvais.

De mon sharepoint vue:

  • l’authentification n’est pas interdite pour RESTfulness (sinon il y aurait peu d’utilisation dans les services RESTful)
  • l’authentification se fait en envoyant un jeton d’authentification dans la requête, 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 une authentification)

Votre sharepoint vue était assez solide. Le seul problème concernait le concept de création d’un jeton d’authentification sur le serveur. Vous n’avez pas besoin de cette partie. Ce dont vous avez besoin, c’est de stocker le nom d’utilisateur et le mot de passe sur le client et de l’envoyer avec chaque demande. Pour cela, vous n’avez pas besoin de plus que l’authentification de base HTTP et une connexion chiffrée:

Figure 1. - Authentification sans état par des clients de confiance

  • Figure 1. – Authentification sans état par des clients de confiance

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 requête.

Maintenant, cela fonctionne plutôt bien avec des clients de confiance que vous avez écrits, mais qu’en est-il des clients tiers? Ils ne peuvent pas avoir le nom d’utilisateur et mot de passe et toutes les permissions des utilisateurs. Vous devez donc stocker séparément les permissions qu’un client tiers peut avoir par un utilisateur spécifique. Les développeurs clients peuvent donc enregistrer des clients tiers et obtenir une clé API unique et les utilisateurs peuvent autoriser des clients tiers à accéder à certaines de leurs permissions. Tout comme la lecture du nom et de l’adresse e-mail, ou la liste de leurs amis, etc. Après avoir autorisé un client tiers, le serveur générera un jeton d’access. Ces jetons d’access peuvent être utilisés par le client tiers pour accéder aux permissions accordées par l’utilisateur, comme suit:

Figure 2. - Authentification sans état par des clients tiers

  • Figure 2. – Authentification sans état par des clients tiers

Ainsi, le client tiers peut obtenir le jeton d’access à partir d’un client de confiance (ou directement de l’utilisateur). Après cela, il peut envoyer une requête valide avec la clé API et le jeton d’access. C’est le mécanisme d’authentification tiers le plus fondamental. Vous pouvez en savoir plus sur les détails de l’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ûr. Par exemple, vous pouvez signer les détails de chaque requête côté serveur et envoyer la signature avec la demande, etc. La solution dépend des besoins de votre application.

Tout d’abord, REST n’est pas une religion et ne doit pas être abordé en tant que tel. Bien que les services RESTful présentent des avantages, vous ne devez suivre les principes de REST que dans la mesure où ils conviennent à votre application.

Cela dit, l’authentification et l’état côté client ne violent pas les principes REST. Bien que REST exige 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’apasortingdie est que le SERVEUR est apasortingde, pas les clients. Tout client émettant une requête 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, REST serait alors violé. Un autre client avec des informations de requête identiques serait placé dans un emplacement différent en fonction de l’état côté serveur.

Les services Web de Google sont un exemple fantastique de système RESTful. Ils nécessitent un en-tête d’authentification avec la clé d’authentification de l’utilisateur à transmettre à chaque requête. Cela enfreint légèrement les principes REST, car le serveur suit l’état de la clé d’authentification. L’état de cette clé doit être maintenu et il a une sorte de date / heure d’expiration après laquelle il ne donne plus access. Cependant, comme je l’ai mentionné en haut de mon message, des sacrifices doivent être faits pour permettre à une application de fonctionner. Cela dit, les jetons d’authentification doivent être stockés de manière à permettre à tous les clients possibles de continuer à accorder l’access pendant leurs heures 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 l’exécution des demandes basées sur cette clé, vous avez commencé à violer réellement les principes de REST. Les services Google garantissent que, à tout moment, vous pouvez prendre un jeton d’authentification que vous utilisiez sur votre téléphone contre le serveur de répartition de la charge A et accéder au serveur B et accéder aux mêmes ressources si les demandes étaient identiques.

Tout cela signifie que vous devez vous assurer que vos jetons d’authentification sont validés par rapport à un magasin de sauvegarde (firebase database, 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 de représentation si vous ne l’avez pas déjà fait. Il est particulièrement éclairant en ce qui concerne ce que les principes de REST préconisent et pourquoi.

Les cookies ne sont pas destinés à l’authentification. Pourquoi réinventer une roue? HTTP dispose de mécanismes d’authentification bien conçus. Si nous utilisons des cookies, nous n’utilisons que HTTP comme protocole de transport, nous devons donc créer notre propre système de signalisation, par exemple pour indiquer aux utilisateurs qu’ils ont fourni une mauvaise authentification (l’utilisation de HTTP 401 serait incorrecte car nous ne le ferions probablement pas). fournissez Www-Authenticate à un client, comme l’exigent les spécifications HTTP :)). Il convient également de noter que Set-Cookie est uniquement une recommandation pour le client. Son contenu peut être ou ne pas être enregistré (par exemple, si les cookies sont désactivés), tandis que l’en-tête d’ Authorization 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 d’abord? Si oui, alors ne serait-ce pas RESTless? Exemple simple:

  • Vous essayez GET /a sans cookie
  • Vous obtenez une demande d’autorisation en quelque sorte
  • Vous allez autoriser comme POST /auth
  • Vous obtenez Set-Cookie
  • Vous essayez GET /a avec GET /a cookie. Mais GET /a se comporte-t-il idempotivement dans ce cas?

Pour résumer, 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.

En réalité, RESTfulness ne s’applique qu’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 si cela se fait régulièrement via HTTP.

Le déterminant principal est le suivant: si vous envoyez un appel REST, qui est un URI, une fois que l’appel parvient au 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 requête n’a pas encore été envoyée au serveur, ce qui signifie le servlet ou l’application qui renverra le document correspondant à l’URI donné.

De même, dans le cas d’un POST ou d’un PUT, pouvez-vous envoyer un URI / payload donné, et quel que soit le nombre de fois que vous envoyez le message, il mettra toujours à jour les mêmes données pour que les GET suivants obtiennent un résultat cohérent?

REST concerne les données d’application et non les informations de bas niveau requirejses pour transférer ces données.

Dans le billet de blog suivant, Roy Fielding a bien résumé l’idée de REST:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841

“Un système RESTful passe d’un état stable à un autre, et chaque état stable est à la fois un état de démarrage potentiel et un état final potentiel. Par exemple, un système RESTful est un nombre inconnu de composants obéissant à un ensemble simple de composants. des règles telles qu’elles soient toujours à l’état REST ou passant 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 état à la fois (l’état d’équilibre actuel) et donc chaque état est simple et peut être analysé indépendamment. l’utilisateur, OTOH, est capable de créer ses propres transitions à tout moment (par exemple, entrez une URL, sélectionnez un signet, ouvrez un éditeur, etc.).


En ce qui concerne l’authentification, que ce soit par le biais de cookies ou d’en-têtes, tant que les informations ne font pas partie des données URI et POST, cela n’a rien à voir avec REST. Donc, en ce qui concerne l’apasortingdie, nous ne parlons que des données de l’application.

Par exemple, lorsque l’utilisateur entre des données dans un écran GUI, le client garde la trace des champs qui ont été saisis, des champs obligatoires manquants, etc. Ceci est tout CLIENT CONTEXT, et ne doit pas être envoyé ou suivi par le serveur. Ce qui est envoyé au serveur est l’ensemble complet des champs qui doivent être modifiés dans la ressource IDENTIFIED (par l’URI), de sorte qu’une transition se produise dans cette ressource d’un état RESTful à un autre.

Ainsi, le client garde la trace de ce que fait l’utilisateur et envoie uniquement des transitions d’état logiquement complètes au serveur.

La transaction HTTP, authentification d’access de base, ne convient pas pour RBAC, car l’authentification d’access de base utilise le nom d’utilisateur crypté: mot de passe à chaque fois, tandis que RBAC doit utiliser le rôle que l’utilisateur souhaite utiliser pour un appel spécifique. RBAC ne valide pas les permissions sur le nom d’utilisateur, mais sur les rôles.

Vous pourriez vous contenter de concaténer comme ceci: usernameRole: password, mais c’est une mauvaise pratique, et elle est également inefficace car lorsqu’un utilisateur a plus de rôles, le moteur d’authentification doit tester tous les rôles dans la concaténation. Cela détruirait l’un des plus grands avantages techniques du RBAC, à savoir un test d’autorisation très rapide.

Ce problème ne peut donc pas être résolu en utilisant une authentification d’access 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 que REST ne devrait pas être traité comme une religion. Dans les parsings de rentabilisation complexes, dans les soins de santé, par exemple, le RBAC est absolument commun 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 via 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 heureux de l’entendre.

  1. Les sessions ne sont pas RESTless
  2. Voulez-vous dire que le service REST pour http-utilise uniquement ou que je me trompe? La session basée sur les cookies ne doit être utilisée que pour les propres services basés sur http! (Cela peut être un problème de travailler avec des cookies, par exemple à partir de Mobile / Console / Desktop / etc.)
  3. Si vous fournissez un service RESTful aux développeurs 3D, n’utilisez jamais de session basée sur les cookies, utilisez plutôt des jetons pour éviter les problèmes de sécurité.