HTTP 401 - Quelle est la valeur d'en-tête WWW-Authenticate appropriée?

109

L'application sur laquelle je travaille en ce moment a une valeur de délai d'expiration de session. Si l'utilisateur n'a pas interagi plus longtemps que cette valeur, la page suivante qu'il essaiera de charger, il sera invité à se connecter.

Toutes les demandes effectuées sont acheminées via ce mécanisme, qui inclut les appels AJAX. À l'origine, nous envoyions un en-tête 200 avec la page de connexion, ce qui introduit des problèmes avec AJAX car le code est exécuté si une réponse 200 est envoyée, et la plupart des données renvoyées à partir de ces appels RPC sont du JSON ou du JavaScript brut qui est évalué (ne demander: |).

J'ai suggéré qu'un 401 est meilleur, car notre analyseur JSON n'essaiera pas de consommer une page de connexion HTML .. :)

Lors de la lecture de la spécification , cependant, j'ai remarqué que le WWW-Authenticatechamp doit également être envoyé.

Quelle est une bonne valeur pour ce champ? Application LoginSuffira- t-il ?

Will Morgan
la source

Réponses:

67

Lors de l'indication de l'authentification de base HTTP, nous renvoyons quelque chose comme:

WWW-Authenticate: Basic realm="myRealm"

Alors que Basicc'est le régime et le reste dépend beaucoup de ce régime. Dans ce cas, realm fournit simplement au navigateur un littéral qui peut être affiché à l'utilisateur lorsqu'il lui demande l'ID utilisateur et le mot de passe.

Cependant, vous n'utilisez évidemment pas Basic, car il ne sert à rien d'avoir une expiration de session lorsque l'authentification de base est utilisée. Je suppose que vous utilisez une forme d'authentification basée sur les formulaires.

De mémoire, Windows Challenge Response utilise un schéma différent et des arguments différents.

L'astuce est que c'est au navigateur de déterminer les schémas qu'il prend en charge et comment il y répond.

Mon instinct si vous utilisez l'authentification basée sur les formulaires est de rester avec la page de connexion 200 + mais d'ajouter un en-tête personnalisé que le navigateur ignorera mais que votre AJAX pourra identifier.

Pour une très bonne expérience User + AJAX, faites en sorte que le script se raccroche à la requête AJAX qui a trouvé la session expirée, lancez une requête de reconnexion via une fenêtre contextuelle et, en cas de succès, soumettez à nouveau la requête AJAX d'origine et continuez comme d'habitude.

Évitez la triche qui fait que le script arrive sur le site toutes les 5 minutes pour maintenir la session en vie, car cela ne fait que battre le point d'expiration de la session.

L'autre alternative est de graver la requête AJAX, mais c'est une mauvaise expérience utilisateur.

Swanny
la source
2
Merci mon pote, j'utilise maintenant un 403 à la place car ce n'est pas une redirection et il inclut littéralement le formulaire de connexion à la place de la page d'origine. Il correspond également mieux à la spécification W3. Merci pour les informations cependant.
Will Morgan
2
Voir cette réponse sur la façon dont vous pouvez toujours utiliser HTTP 401: stackoverflow.com/questions/928874/…
lanoxx
Oui, mettez n'importe quoi dans l'en-tête WWW-Authenticate, je suppose. Une autre réponse dans la même veine est stackoverflow.com/a/1088127/689161 Ou simplement violer les spécifications et ne pas prendre la peine d'envoyer l'en-tête (au moins quelques sites le font); 401 est toujours plus approprié que 403.
gengkev
Je ne suis pas sûr que je "mettrais n'importe quoi" dans l'en-tête WWW-Authenticate car je ne peux pas être sûr que la demande est gérée par mon ajax ou le navigateur. Au-delà du titre de cette question, étant donné le détail qui suggère l'authentification basée sur les formulaires, je n'enverrais aucun en-tête WWW-Authenticate. C'est parce que je ne demande pas au navigateur de participer au défi d'authentification / d'identification. Je veux juste qu'il montre un formulaire qui se trouve être un formulaire de connexion, mais avec quelque chose que l'ajax peut utiliser pour l'identifier, c'est un formulaire de connexion afin qu'il puisse le gérer différemment comme ci-dessus.
Swanny
Vous devez créer un schéma d'authentification à utiliser avec l'en-tête. Ensuite, le navigateur ne sera pas impliqué car il ne comprendra pas le schéma. Certains clients sont contrariés ou confus si vous n'incluez pas l'en-tête.
KayEss
-7

Lorsque la session utilisateur expire, je renvoie un code d'état HTTP 204. Notez que l'état HTTP 204 ne contient aucun contenu. Du côté client, je fais ceci:

xhr.send(null);
if (xhr.status == 204) 
    Reload();
else 
    dropdown.innerHTML = xhr.responseText;

Voici la fonction Reload ():

function Reload() {
    var oForm = document.createElement("form");
    document.body.appendChild(oForm);
    oForm.submit();
    }
Smurfling
la source
6
Comment se fait-il que vous utilisiez HTTP 204? developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
Will Morgan