Quel est le code d'état HTTP correct lors de la redirection vers une page de connexion?

133

Lorsqu'un utilisateur n'est pas connecté et tente d'accéder à une page qui nécessite une connexion, quel est le code d'état HTTP correct pour une redirection vers la page de connexion?

Je demande car aucun des codes de réponse 3xx définis par le W3C ne semble répondre aux exigences:

10.3.1 300 choix multiples

La ressource demandée correspond à l'une quelconque d'un ensemble de représentations, chacune avec son propre emplacement spécifique, et des informations de négociation pilotées par l'agent (section 12) sont fournies afin que l'utilisateur (ou l'agent utilisateur) puisse sélectionner une représentation préférée et rediriger son demande à cet endroit.

À moins qu'il ne s'agisse d'une demande HEAD, la réponse DEVRAIT inclure une entité contenant une liste de caractéristiques de ressources et d'emplacements à partir desquels l'utilisateur ou l'agent d'utilisateur peut choisir celui qui convient le mieux. Le format d'entité est spécifié par le type de média indiqué dans le champ d'en-tête Content-Type. Selon le format et les capacités de

l'agent utilisateur, la sélection du choix le plus approprié PEUT être effectuée automatiquement. Cependant, cette spécification ne définit aucune norme pour une telle sélection automatique.

Si le serveur a un choix préféré de représentation, il DEVRAIT inclure l'URI spécifique pour cette représentation dans le champ Location; les agents utilisateurs PEUVENT utiliser la valeur du champ Location pour la redirection automatique. Cette réponse peut être mise en cache, sauf indication contraire.

10.3.2 301 déplacé définitivement

Un nouvel URI permanent a été attribué à la ressource demandée et toute référence future à cette ressource DEVRAIT utiliser l'un des URI renvoyés. Les clients dotés de capacités d'édition de liens doivent automatiquement relier les références à l'URI de demande à une ou plusieurs des nouvelles références renvoyées par le serveur, si possible. Cette réponse peut être mise en cache, sauf indication contraire.

Le nouvel URI permanent DEVRAIT être donné par le champ Location dans la réponse. À moins que la méthode de demande ne soit HEAD, l'entité de la réponse DEVRAIT contenir une courte note hypertexte avec un lien hypertexte vers le ou les nouveaux URI.

Si le code d'état 301 est reçu en réponse à une demande autre que GET ou HEAD, l'agent utilisateur NE DOIT PAS rediriger automatiquement la demande à moins qu'elle ne puisse être confirmée par l'utilisateur, car cela pourrait changer les conditions dans lesquelles la demande a été émise.

  Note: When automatically redirecting a POST request after
  receiving a 301 status code, some existing HTTP/1.0 user agents
  will erroneously change it into a GET request.

10.3.3 302 Trouvé

La ressource demandée réside temporairement sous un URI différent. Puisque la redirection peut être modifiée à l'occasion, le client DEVRAIT continuer à utiliser l'URI de demande pour les demandes futures. Cette réponse peut être mise en cache uniquement si elle est indiquée par un champ d'en-tête Cache-Control ou Expires.

L'URI temporaire DEVRAIT être donnée par le champ Location dans la réponse. À moins que la méthode de demande ne soit HEAD, l'entité de la réponse DEVRAIT contenir une courte note hypertexte avec un lien hypertexte vers le ou les nouveaux URI.

Si le code d'état 302 est reçu en réponse à une demande autre que GET ou HEAD, l'agent utilisateur NE DOIT PAS rediriger automatiquement la demande à moins qu'elle ne puisse être confirmée par l'utilisateur, car cela pourrait changer les conditions dans lesquelles la demande a été émise.

  Note: RFC 1945 and RFC 2068 specify that the client is not allowed
  to change the method on the redirected request.  However, most
  existing user agent implementations treat 302 as if it

étaient une réponse 303, effectuant un GET sur la valeur du champ Location indépendamment de la méthode de demande d'origine. Les codes d'état 303 et 307 ont été ajoutés pour les serveurs qui souhaitent clarifier sans ambiguïté quel type de réaction est attendu du client.

10.3.4 303 Voir Autre

La réponse à la demande peut être trouvée sous un URI différent et DEVRAIT être récupérée en utilisant une méthode GET sur cette ressource. Cette méthode existe principalement pour permettre la sortie d'un script activé par POST pour rediriger l'agent utilisateur vers une ressource sélectionnée. Le nouvel URI n'est pas une référence de remplacement pour la ressource demandée à l'origine. La réponse 303 NE DOIT PAS être mise en cache, mais la réponse à la seconde demande (redirigée) peut être mise en cache.

L'URI différent DEVRAIT être donné par le champ Location dans la réponse. À moins que la méthode de demande ne soit HEAD, l'entité de la réponse DEVRAIT contenir une courte note hypertexte avec un lien hypertexte vers le ou les nouveaux URI.

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
  status. When interoperability with such clients is a concern, the
  302 status code may be used instead, since most user agents react
  to a 302 response as described here for 303.

10.3.5 304 Non modifié

Si le client a effectué une demande conditionnelle GET et que l'accès est autorisé, mais que le document n'a pas été modifié, le serveur DEVRAIT répondre avec ce code d'état. La réponse 304 NE DOIT PAS contenir de corps de message, et est donc toujours terminée par la première ligne vide après les champs d'en-tête.

La réponse DOIT inclure les champs d'en-tête suivants:

  - Date, unless its omission is required by section 14.18.1 If a

Le serveur d'origine sans horloge obéit à ces règles, et les mandataires et les clients ajoutent leur propre date à toute réponse reçue sans une (comme déjà spécifié par [RFC 2068], section 14.19), les caches fonctionneront correctement.

  - ETag and/or Content-Location, if the header would have been sent
    in a 200 response to the same request
  - Expires, Cache-Control, and/or Vary, if the field-value might
    differ from that sent in any previous response for the same
    variant If the conditional GET used a strong cache validator (see

section 13.3.3), la réponse NE DEVRAIT PAS inclure d'autres en-têtes d'entité. Sinon (c'est-à-dire que le GET conditionnel a utilisé un validateur faible), la réponse NE DOIT PAS inclure d'autres en-têtes d'entité; cela évite les incohérences entre les corps d'entités mis en cache et les en-têtes mis à jour.

Si une réponse 304 indique une entité qui n'est pas actuellement mise en cache, alors l'antémémoire DOIT ignorer la réponse et répéter la demande sans le conditionnel.

Si une antémémoire utilise une réponse 304 reçue pour mettre à jour une entrée d'antémémoire, l'antémémoire DOIT mettre à jour l'entrée pour refléter toute nouvelle valeur de champ donnée dans la réponse.

10.3.6 305 Utiliser un proxy

La ressource demandée DOIT être accédée via le proxy donné par le champ Location. Le champ Location donne l'URI du proxy. Le destinataire est censé répéter cette demande unique via le proxy. 305 réponses DOIVENT être générées uniquement par les serveurs d'origine.

  Note: RFC 2068 was not clear that 305 was intended to redirect a
  single request, and to be generated by origin servers only.  Not
  observing these limitations has significant security consequences.

10.3.7 306 (inutilisé)

Le code d'état 306 a été utilisé dans une version précédente de la spécification, n'est plus utilisé et le code est réservé.

10.3.8 307 Redirection temporaire

La ressource demandée réside temporairement sous un URI différent. Puisque la redirection PEUT être modifiée à l'occasion, le client DEVRAIT continuer à utiliser l'URI-de-demande pour les demandes futures. Cette réponse ne peut être mise en cache que si elle est indiquée par un champ d'en-tête Cache-Control ou Expires.

L'URI temporaire DEVRAIT être donnée par le champ Location dans la réponse. À moins que la méthode de demande ne soit HEAD, l'entité de la réponse DEVRAIT contenir une courte note hypertexte avec un lien hypertexte vers le ou les nouveaux URI, car de nombreux agents utilisateurs pré-HTTP / 1.1 ne comprennent pas l'état 307. Par conséquent, la note DEVRAIT contenir les informations nécessaires pour qu'un utilisateur répète la demande d'origine sur le nouvel URI.

Si le code d'état 307 est reçu en réponse à une demande autre que GET ou HEAD, l'agent utilisateur NE DOIT PAS rediriger automatiquement la demande à moins qu'elle ne puisse être confirmée par l'utilisateur, car cela pourrait changer les conditions dans lesquelles la demande a été émise.

J'utilise 302 pour l'instant, jusqu'à ce que je trouve la bonne réponse.

Mise à jour et conclusion:

HTTP 302 est meilleur car il est connu pour avoir la meilleure compatibilité avec les clients / navigateurs.

Vidar Vestnes
la source
1
Je dirais que la manière absolue serait de renvoyer un 401 et une page de connexion sans redirection, mais je ne suis pas sûr de vos options.
Nick Craver
1
@Nick bon point, mais je craindrais des effets secondaires si je construisais un système de connexion classique.
Pekka
1
@Pekka - Tout à fait d'accord, cela dépend de la plate-forme sur laquelle il se trouve pour savoir comment tout ce qui peut être géré proprement, même si c'est un intranet vs Internet entre en jeu, je crois ... vous faites généralement l'authentification d'une manière différente sur un intranet, Tout du moins selon moi.
Nick Craver
@Nick With 401 "La réponse DOIT inclure un champ d'en-tête WWW-Authenticate" - Comment puis-je combiner cela avec une base de données MySQL? AuthType Basic et Digest ne sont-ils pas limités aux fichiers de configuration Apache comme .htpassword etc ...?
Vidar Vestnes
Je veux une page de connexion personnalisée, pas la boîte de dialogue de base du navigateur demandant le nom d'utilisateur et le mot de passe ...
Vidar Vestnes

Réponses:

66

Je dirais 303 voir d'autres 302 trouvés:

La ressource demandée réside temporairement sous un URI différent. Puisque la redirection peut être modifiée à l'occasion , le client DEVRAIT continuer à utiliser l'URI de demande pour les demandes futures. Cette réponse ne peut être mise en cache que si elle est indiquée par un champ d'en-tête Cache-Control ou Expires.

correspond le mieux à une page de connexion à mon avis. J'ai d'abord envisagé 303 see otherce qui fonctionnerait aussi bien. Après réflexion, je dirais que 302 Foundc'est plus approprié car la ressource demandée a été trouvée, il y a juste une autre page à parcourir avant de pouvoir y accéder. La réponse n'est pas mise en cache par défaut, ce qui convient également.

Pekka
la source
4
Je suis d'accord, mais je pense que 302 Found indique que la ressource a été trouvée, juste sous une autre URL. Ex. Je veux voir / mes-messages / la réponse du serveur avec un 302 car "aujourd'hui" mes messages se trouvent dans "/ login /" (au lieu de "/ messages /") ... J'utilise 302, mais je ne le sens pas le contexte correspond à 100%. La page de connexion étant une ressource différente et n'ayant pas le même contenu que celui demandé.
Vidar Vestnes
2
@PHP_Jedi vrai. 303 peut être plus approprié de ce point de vue. Cependant, 302 est plus fiable en termes de compatibilité client.
Pekka
1
Oui, je pense que 303 pourrait mieux s'adapter au contexte car il déclare "La réponse à la demande peut être trouvée sous un URI différent". Cela me dit que ce n'est pas la ressource elle-même qui se trouve dans un autre URI, mais seulement la réponse à cette demande.
Vidar Vestnes
3
@PHP_Jedi Je ne sais pas si cela vaut la peine d'y consacrer autant de temps. Les clients et les serveurs dans le monde http doivent de toute façon être extrêmement libéraux et tolérants aux pannes, il n'y aura donc pas de réelle différence si vous utilisez 302ou 303, sauf que 302c'est mieux connu. Je trouve le niveau de détail louable et il est toujours bon de bien faire les choses, mais trop d'efforts peuvent être vains dans ce domaine spécifique.
Pekka
28
Pour info: Google émet 302s
David Murdoch
51

Il s'agit d'une mauvaise utilisation du mécanisme de redirection HTTP. Si l'utilisateur n'est pas autorisé, votre application doit revenir 401 Unauthorized. Dans le cas où l'utilisateur est autorisé mais n'a pas accès à la ressource demandée, il 403 Forbiddendoit alors être retourné.

Vous devez faire la redirection côté client, par exemple par javascript. code d'état pour la redirection car l'autorisation requise n'existe pas . L'utilisation de 30x pour cela n'est pas conforme à HTTP.

Comment penser aux codes d'état HTTP par Mark Nottingham

401 Unauthorized déclenche le mécanisme d'authentification des requêtes HTTP.

401 Unauthorized le code d'état nécessite la présence de WWW-Authenticate tête prenant en charge divers types d'authentification:

Authentification WWW: <type> realm = <realm>

Porteur, OAuth, Basic, Digest, Cookie, etc.

filip26
la source
20
Un 401 peut ne pas être approprié dans certains cas comme A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field( RFC ), et tous les systèmes de connexion n'utilisent pas cet en-tête.
starbeamrainbowlabs
6
Supposons que vous actualisez une page protégée; Le javascript côté client n'aura aucun changement pour être appelé, et le navigateur affichera une fenêtre de connexion au lieu de rediriger l'utilisateur vers la page de connexion - donc le seul moyen est d'utiliser un code 30x.
Claude Brisson
2
Golang ne peut pas utiliser 401 pour la redirection. Cela signifie que nous devrions utiliser 30 * pour les redirections.
EIMEI
4
@EIMEI suivant votre raisonnement, si une autre langue ou bibliothèque vous obligeait à utiliser 401, alors Internet serait voué à l'échec. Mon point est: ce que vous dites indique un problème avec Golang (bien que je trouve surprenant qu'il aurait une telle conception pour rendre impossible l'envoi de 401!)
Greg
2
@starbeamrainbowlabs Il existe un brouillon pour l'authentification HTTP basée sur les cookies en option dans l'en-tête WWW-Authenticate. Voir: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef
12

Je pense que la solution appropriée est l'en-tête HTTP 401 (non autorisé).

http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

Le but de cet en-tête est exactement ceci. Mais, au lieu de rediriger vers une page de connexion, le processus correct serait quelque chose comme:

  • L'utilisateur non connecté tente d'accéder à une page à connexion restreinte.
  • le système identifie l'utilisateur n'est pas connecté
  • le système renvoie l'en-tête HTTP 401 ET affiche le formulaire de connexion dans la même réponse (pas une redirection).

C'est une bonne pratique, comme fournir une page 404 utile, avec des liens de plan du site et un formulaire de recherche par exemple.

À plus.

Davis Peixoto
la source
20
Le RFC déclare: "La réponse DOIT inclure un champ d'en-tête WWW-Authenticate (paragraphe 14.46) contenant un défi applicable à la ressource demandée." Une réponse 401 n'est vraiment applicable que lors de l'utilisation d'un schéma d'authentification HTTP.
bshacklett
4
Dans ce cas, 403 serait mieux car il indique que l'accès est simplement interdit et que l'en-tête d'autorisation n'aidera pas
olanod
@bshacklett WWW-Authenticate peut être utilisé avec de nombreux schémas d'authentification (par exemple Bearer, OAuth). Voir developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… et iana.org/assignments/http-authschemes/http-authschemes.xhtml
filip26
Il existe un brouillon pour l'authentification HTTP basée sur les cookies en option dans l'en-tête WWW-Authenticate. Voir: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef