126 votes

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

Il s'agit d'une question conceptuelle.

J'ai une application client (mobile) qui doit prendre en charge une action de connexion à un service web RESTful. Comme le service web est RESTful, cela revient à ce que le client accepte un nom d'utilisateur/mot de passe de la part de l'utilisateur, vérifie ce nom d'utilisateur/mot de passe avec le service, puis se rappelle simplement 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 et un mot de passe donnés sont valides, le service Web doit-il toujours répondre avec des données JSON m'indiquant si la requête est réussie ou non, ou doit-il renvoyer HTTP 200 si les informations d'identification sont bonnes et HTTP 401 si elles sont mauvaises ?

La raison de ma question est que certains autres services RESTful utilisent l'adresse 401 en cas d'informations d'identification erronées, même lorsque vous demandez simplement si les informations d'identification sont valides. Cependant, selon ma compréhension des 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 à tous, car son objectif est de vous indiquer 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 

doit retourner 401 si de mauvaises informations d'identification sont fournies. Mais une requête comme :

myservice.com/are/these/credentials/valid

ne devrait jamais renvoyer 401 car cette URL particulière (demande) est autorisée avec ou sans informations d'identification valides.

J'aimerais entendre des avis justifiés dans un sens ou dans l'autre sur cette question. Quelle est la manière standard de traiter cette question, et cette manière standard est-elle logiquement appropriée ?

149voto

Cleric Points 2931

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

401 Non autorisé Similaire à 403 Forbidden, mais spécifiquement utilisé 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 sur, myservice.com/are/these/credentials/valid renvoyer 401 alors que vous ne faites qu'une vérification, je pense que cela est dû au fait que les contraintes RESTful ne permettent pas de faire des requêtes booléennes. Chaque requête doit renvoyer une ressource. Faire des questions booléennes dans un service RESTful est une pente glissante vers RPC.

Maintenant, je ne sais pas comment se comportent les services sur lesquels vous avez regardé. Mais une bonne façon 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 faire une "vérification", 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 qui seraient autrement difficiles à créer des ressources individuelles.

35voto

vinksharma Points 51

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 n'est pas le bon code d'erreur à mon avis.

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

*10.4.2 401 Unauthorized (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 contenait déjà des informations d'autorisation, la réponse 401 indique que l'autorisation a été refusée pour ces informations. 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é pourrait inclure des informations de diagnostic pertinentes. L'authentification d'accès HTTP est expliquée dans "HTTP Authentication : Basic and Digest Access Authentication" [43].*

1voto

AVV Points 94

Si le code de réponse 401 est trompeur pour l'authentification de l'utilisateur, l'API peut envoyer le code d'état HTTP 200 OK pour l'authentification réussie et l'échec de l'authentification, mais définir un en-tête personnalisé sur la réponse d'authentification réussie et omettre cet en-tête sur les connexions échouées.

Le client peut vérifier si l'en-tête existe ou non et décider de l'action à entreprendre.

Exemple : Réponse de l'API SpringBoot

L'appel à OK lorsque la connexion est réussie place l'en-tête "gotyouin" avec une valeur (n'importe quoi). L'appel à failed n'ajoute pas l'en-tête et le client peut traiter cela comme une tentative de connexion ratée.

public class LoginResponseEntityHelper {
   public static ResponseEntity<?> ok(String token) {
       return ResponseEntity.status(HttpStatus.OK).header("gotyouin", token).body(null);
    }

    public static ResponseEntity<?> failed() {
        return ResponseEntity.status(HttpStatus.OK).body(null);
    }}

-6voto

shrimpwagon Points 124

Retournez 409 avec un message d'erreur approprié.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X