Échec de la connexion RESTful: retour 401 ou réponse personnalisée

103

C'est une question conceptuelle.

J'ai une application client (mobile) qui doit prendre en charge une action de connexion sur un service Web RESTful. Étant donné que le service Web est RESTful, cela revient au client d'accepter un nom d'utilisateur / mot de passe de l'utilisateur, de vérifier ce nom d'utilisateur / mot de passe avec le service, puis de se souvenir d'envoyer ce nom d'utilisateur / mot de passe avec toutes les demandes suivantes.

Toutes les autres réponses de ce service Web sont fournies au format JSON.

La question est la suivante: lorsque j'interroge le service Web simplement pour savoir si un nom d'utilisateur / mot de passe donné est valide, le service Web doit-il toujours répondre avec des données JSON m'indiquant son succès ou son échec, ou doit-il renvoyer HTTP 200 avec de bonnes informations d'identification et HTTP 401 sur de mauvaises informations d'identification.

La raison pour laquelle je demande est que certains autres services RESTful utilisent 401 pour de mauvaises informations d'identification, même lorsque vous demandez simplement si les informations d'identification sont valides. Cependant, si je comprends bien les réponses 401, elles représentent une ressource à laquelle vous n'êtes pas censé avoir accès sans informations d'identification valides. Mais la ressource de connexion DEVRAIT être accessible à tout le monde car le but entier de la ressource de connexion est de vous dire si vos informations d'identification sont valides.

En d'autres termes, il me semble qu'une demande comme:

myservice.com/this/is/a/user/action 

devrait retourner 401 si de mauvaises informations d'identification sont fournies. Mais une demande comme:

myservice.com/are/these/credentials/valid

ne doit jamais retourner 401 car cette URL (requête) particulière est autorisée avec ou sans informations d'identification valides.

J'aimerais entendre des opinions justifiées d'une manière ou d'une autre à ce sujet. Quelle est la manière standard de gérer cela et la manière standard de gérer cela est-elle logiquement appropriée?

Mat
la source

Réponses:

128

Tout d'abord. 401 est le code de réponse approprié à envoyer en cas d'échec de la connexion.

401 Non autorisé Similaire à 403 Interdit, mais spécifiquement à utiliser lorsque l'authentification est requise et a échoué ou n'a pas encore été fournie. La réponse doit inclure un champ d'en-tête WWW-Authenticate contenant un défi applicable à la ressource demandée.

Votre confusion à propos du myservice.com/are/these/credentials/validrenvoi de 401 lorsque vous faites juste une vérification, je pense, est basée sur le fait que faire des requêtes booléennes dans REST est souvent faux par les contraintes RESTful. Chaque demande doit renvoyer une ressource. Faire des questions booléennes dans un service RESTful est un sloop glissant vers RPC.

Maintenant, je ne sais pas comment se comportent les services que vous avez consultés. Mais un bon moyen de résoudre ce problème est d'avoir quelque chose comme un objet Account, que vous essayez d'obtenir. Si vos informations d'identification sont correctes, vous obtiendrez l'objet Account, si vous ne voulez pas gaspiller de la bande passante juste pour un "check", vous pouvez faire un HEAD sur la même ressource.

Un objet de compte est également un bon endroit pour stocker toutes ces valeurs booléennes embêtantes pour lesquelles il serait autrement difficile de créer des ressources individuelles.

Clerc
la source
2
Votre point sur le retour des ressources semble valable et c'est peut-être la bonne décision ici. Quant à dire que 401 est la bonne réponse, j'apprécierais quelques explications. J'ai lu les spécifications HTTP, comme vous l'avez inclus ici, mais cela ne me lit pas comme une confirmation directe et évidente de votre assertion. À savoir, l'authentification n'est PAS requise pour poser des questions sur la validité des informations d'identification - mais ce que vous avez inclus dit "spécifiquement à utiliser lorsque l'authentification est requise".
Matt
3
Votre façon de voir les choses est correcte. Vous n'avez pas besoin d'être authentifié pour pouvoir demander votre objet Compte. Mais vous devez vous authentifier avec succès pour pouvoir recevoir la ressource, et c'est le authentication is required and has failed or has not yet been providedcas, puisque vous ne demandez pas la validité des informations d'identification, mais une ressource spécifique basée sur les informations d'identification que vous fournissez.
Cleric
2
Je comprends pourquoi vous voulez faire un "check-call" et pour cela, je recommanderais toujours 401 comme code de réponse approprié pour une authentification échouée, même si l'appel ne nécessite pas d'authentification pour être appelable. Un 204 No Content peut également convenir, mais semble un peu ambigu.
Cleric
4
Je ne vois pas comment cela peut être correct, sauf si vous utilisez l'authentification de base ou Digest. Selon la partie citée de la spécification: "La réponse doit inclure une authentification WWW" - et si vous vous référez à la section 14.47: "Le processus d'authentification de l'accès HTTP est décrit dans" Authentification HTTP: authentification d'accès de base et Digest ". Cela implique pour moi, que 401 n'est pas approprié si vous utilisez la validation typique d'email / mot de passe.
Jonah
1
Je pense que cela peut être faux, j'ai implémenté des clients Web et mobiles et j'intercepte 401 pour rediriger vers l'écran de connexion. Mais quand quelqu'un est déjà sur l'écran de connexion et soumet de mauvaises informations d'identification, la réponse a également 401 et essaiera à nouveau de rediriger. Il devrait y avoir un code d'état différent pour la tentative échouée de s'authentifier lors d'une tentative explicite. Peut-être une mauvaise demande ou même une erreur de serveur?
Japheth Ongeri - inkalimeva
27

401 ne doit être envoyé que lorsque la demande nécessite un champ d'en-tête d'autorisation et que l'autorisation échoue. Étant donné que l'API de connexion ne nécessite pas d'autorisation, 401 est donc le mauvais code d'erreur à mon avis

Selon la norme ici https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 Non autorisé

La demande nécessite une authentification de l'utilisateur. La réponse DOIT inclure un champ d'en-tête WWW-Authenticate (section 14.47) contenant un défi applicable à la ressource demandée. Le client PEUT répéter la demande avec un champ d'en-tête d'autorisation approprié (section 14.8). Si la demande comprenait déjà des informations d'identification d'autorisation, la réponse 401 indique que l'autorisation a été refusée pour ces informations d'identification. Si la réponse 401 contient le même défi que la réponse précédente, et que l'agent utilisateur a déjà tenté l'authentification au moins une fois, alors l'utilisateur DEVRAIT se voir présenter l'entité qui a été donnée dans la réponse, puisque cette entité peut inclure des informations de diagnostic pertinentes. L'authentification de l'accès HTTP est expliquée dans "Authentification HTTP: authentification d'accès de base et Digest" [43]. *

Vinksharma
la source
8
Je suis d'accord avec vous sur ce point, mais quel est le statut de réponse alternatif à envoyer? J'ai implémenté des clients Web et mobiles et j'intercepte 401 pour rediriger vers l'écran de connexion. Mais quand quelqu'un est déjà sur l'écran de connexion et soumet des informations d'identification erronées, la réponse a également 401 et essaiera de rediriger à nouveau ... que feriez-vous?
Japheth Ongeri - inkalimeva
0

Renvoyez 409 avec un message d'erreur approprié.

crevette
la source