web-dev-qa-db-fra.com

Pouvez-vous m'aider à comprendre cela? "Commun REST Erreurs: les sessions ne sont pas pertinentes"

Avis de non-responsabilité: je suis nouveau dans l'école de pensée REST, et j'essaie de m'en occuper.

Donc, je lis cette page, Common REST Mistakes , et j'ai trouvé que je suis complètement dérouté par la section sur les sessions non pertinentes. C'est ce que la page dit:

Il ne devrait pas être nécessaire pour un client de "se connecter" ou de "démarrer une connexion". L'authentification HTTP se fait automatiquement sur chaque message. Les applications client sont des consommateurs de ressources, pas de services. Il n'y a donc rien à se connecter! Supposons que vous réservez un vol sur un service Web REST. Vous ne créez pas de nouvelle connexion "session" au service. Vous demandez plutôt à "l'objet créateur d'itinéraire" de vous créer un nouvel itinéraire. Vous pouvez commencer à remplir les espaces vides, puis obtenir un composant totalement différent ailleurs sur le Web pour remplir d'autres espaces vides. Il n'y a pas de session donc il n'y a pas de problème de migration de l'état de session entre les clients. Il n'y a pas non plus de problème "affinité de session" sur le serveur (bien qu'il y ait encore des problèmes d'équilibrage de charge pour continuer).

D'accord, je comprends que l'authentification HTTP se fait automatiquement sur chaque message - mais comment? Le nom d'utilisateur/mot de passe est-il envoyé avec chaque demande? Cela n'augmente-t-il pas simplement la surface d'attaque? J'ai l'impression de manquer une partie du puzzle.

Serait-il mauvais d'avoir un service REST, disons, /session, qui accepte une demande GET, dans laquelle vous transmettriez un nom d'utilisateur/mot de passe dans le cadre de la demande, et renvoie un jeton de session si l'authentification a réussi, qui pourrait ensuite être transmise avec les demandes suivantes? Est-ce que cela a du sens d'un point de vue REST, ou est-ce que cela manque le point?

159
Rob

Pour être RESTful, chaque requête HTTP doit transporter suffisamment d'informations par elle-même pour que son destinataire la traite pour être en parfaite harmonie avec la nature sans état de HTTP.

D'accord, je comprends que l'authentification HTTP se fait automatiquement sur chaque message - mais comment?

Oui, le nom d'utilisateur et le mot de passe sont envoyés avec chaque demande. Les méthodes courantes pour ce faire sont authentification d'accès de base et authentification d'accès digest. Et oui, un espion peut capturer les informations d'identification de l'utilisateur. On crypterait ainsi toutes les données envoyées et reçues à l'aide de Transport Layer Security (TLS).

Serait-il mauvais d'avoir un service REST, par exemple,/session, qui accepte une demande GET, où vous transmettriez un nom d'utilisateur/mot de passe dans le cadre de la demande et renvoie une session si l'authentification a réussi, cela pourrait être transmis avec les demandes suivantes? Est-ce logique d'un point de vue REST, ou est-ce que cela manque le point?

Ce ne serait pas RESTful car il porte l'état mais il est cependant assez courant car c'est une commodité pour les utilisateurs; un utilisateur n'a pas à se connecter à chaque fois.

Ce que vous décrivez dans un "jeton de session" est communément appelé cookie de connexion. Par exemple, si vous essayez de vous connecter à votre compte Yahoo! compte il y a une case à cocher qui dit "me garder connecté pendant 2 semaines". Cela signifie essentiellement (selon vos mots) "garder mon jeton de session en vie pendant 2 semaines si je me connecte avec succès." Les navigateurs Web enverront ces cookies de connexion (et éventuellement d'autres) à chaque demande HTTP que vous lui demanderez de faire pour vous.

79
z8000

Il n'est pas rare qu'un service REST requiert une authentification pour chaque demande HTTP. Par exemple, Amazon S3 exige que chaque demande ait une signature dérivée des informations d'identification de l'utilisateur, la demande exacte à effectuer , et l'heure actuelle. Cette signature est facile à calculer côté client, peut être rapidement vérifiée par le serveur, et est d'une utilité limitée pour un attaquant qui l'intercepte (car elle est basée sur l'heure actuelle).

33
Greg Hewgill

Beaucoup de gens ne comprennent pas REST principales très clairement, l'utilisation d'un jeton de session ne signifie pas toujours que vous êtes avec état, la raison pour envoyer un nom d'utilisateur/mot de passe à chaque demande est uniquement pour l'authentification et la de même pour l'envoi d'un jeton (généré par le processus de connexion) juste pour décider si le client a la permission de demander des données ou non, vous violez uniquement REST convetions lorsque vous utilisez le nom d'utilisateur/mot de passe ou les jetons de session pour Décidez quelles données afficher! Au lieu de cela, vous devez les utiliser uniquement pour l'authentification (pour afficher les données ou ne pas afficher les données)

dans votre cas, je dis OUI, c'est RESTy, mais essayez d'éviter d'utiliser des sessions PHP natives dans votre REST et commencez à générer vos propres jetons hachés qui expirent dans une période de temps déterminée!

10
EvilThinker

Non, ça ne manque pas le point. ClientLogin de Google fonctionne exactement de cette manière, à l'exception notable que le client est invité à accéder à la "/ session" en utilisant une réponse HTTP 401. Mais cela ne crée pas de session, cela crée uniquement un moyen pour les clients de s'authentifier (temporairement) sans passer les informations d'identification en clair, et pour le serveur de contrôler la validité de ces informations d'identification temporaires comme bon lui semble.

8
mogsie

D'accord, je comprends que l'authentification HTTP se fait automatiquement sur chaque message - mais comment?

"Autorisation:" En-tête HTTP envoyé par le client. Soit basique (texte brut) ou condensé.

Serait-il mauvais d'avoir un service REST, par exemple,/session, qui accepte une demande GET, où vous transmettriez un nom d'utilisateur/mot de passe dans le cadre de la demande et renvoie une session si l'authentification a réussi, cela pourrait être transmis avec les demandes suivantes? Est-ce logique d'un point de vue REST, ou est-ce que cela manque le point?

L'idée de la session est de créer des applications avec état en utilisant le protocole sans état (HTTP) et un client stupide (navigateur Web), en maintenant l'état du côté serveur. L'un des principes REST est "Chaque ressource est adressable de manière unique en utilisant une syntaxe universelle à utiliser dans les liens hypermédias" . Les variables de session ne sont pas accessibles via l'URI. L'application vraiment RESTful maintiendrait l'état du côté client, envoyant toutes les variables nécessaires via HTTP, de préférence dans l'URI.

Exemple: recherche avec pagination. Vous auriez une URL sous forme

http://server/search/urlencoded-search-terms/page_num

Cela a beaucoup en commun avec les URL pouvant être mises en signet

5
vartec

Je pense que votre suggestion est OK, si vous voulez contrôler la durée de vie de la session client. Je pense que l'architecture RESTful vous encourage à développer des applications sans état. Comme l'a écrit @ 2pence "chaque requête HTTP doit transporter suffisamment d'informations par elle-même pour que son destinataire la traite pour être en parfaite harmonie avec la nature sans état de HTTP" .

Cependant, ce n'est pas toujours le cas, parfois l'application doit indiquer quand le client se connecte ou se déconnecte et maintenir des ressources telles que des verrous ou des licences en fonction de ces informations. Voir mon suivi question pour un exemple d'un tel cas.

3
LiorH