web-dev-qa-db-fra.com

Demande CORS avec contrôle en amont et redirection: refusée. Solutions de contournement?

Je conçois une API qui permet à l'utilisateur de s'authentifier (à l'aide de jetons) et qui contient des redirections dans le même domaine. Maintenant, pour une demande non authentifiée à un point de terminaison qui renvoie 303,

GET /documents/123  --> 303 redirect to `/documents/abc`
GET /documents/abc  --> 200

tout fonctionne bien.

Faisons une demande authentifiée au même point de terminaison où l'en-tête Authorization est envoyé. Cela fait de la demande une demande de contrôle en amont et le navigateur effectue une demande de contrôle en amont OPTIONS, c'est-à-dire.

OPTIONS /documents/123   --> 204 (everything okay, please proceed)
GET /documents/123       --> 303 redirect to `/documents/abc`

À ce stade, au lieu de GETting la ressource réelle à /documents/abc, le navigateur cède

XMLHttpRequest cannot load http://localhost:8000/people/username/nschloe. 
The request was redirected to 'http://localhost:8000/people/YDHa-B2FhMie', 
which is disallowed for cross-Origin requests that require preflight.

Ce comportement est conforme à la norme :

7.1.5 Demande d'origine croisée avec contrôle en amont

Si la réponse a un code d'état HTTP qui n'est pas dans la plage 2xx

Appliquez les étapes d'erreur réseau.

Cela semble signifier que l'on ne peut pas faire des redirections pour les ressources authentifiées, même si la redirection est sur le même domaine (localhost).

Est-ce vraiment vrai? Existe-t-il une solution de contournement commune?

23
Nico Schlömer

La norme d'origine empêche la redirection après un contrôle en amont CORS réussi. Citant le § 7.1.5. :

Ceci est la demande réelle. Appliquez les étapes de demande et respectez les règles de demande ci-dessous lors de la demande.

  • Si la réponse a un code d'état HTTP de 301, 302, 303, 307 ou 308 Appliquez les étapes d'erreur de cache et de réseau.

En raison de vos efforts (merci!), Le 4 août, la norme était mise à jour pour autoriser la redirection après la réussite du contrôle en amont de CORS.

Jusqu'à ce que les navigateurs rattrapent leur retard, les seules options possibles semblent être une ou une combinaison de:

  1. Émettre des redirections uniquement pour demandes simples .
  2. Émettez un 5 redirection , avec votre propre URL dans l'en-tête Location en tant que "proxy". Soyez prêt pour une prise en charge limitée du navigateur, car 305 est obsolète.
  3. Faites une fausse "redirection":
    • retourner du HTML avec meta refresh et/ou Javascript Location change.
    • retourne du HTML qui a une fenêtre de remplissage iframe avec la cible de redirection comme source de l'iframe.
    • afficher un lien sur lequel l'utilisateur doit cliquer pour accéder au contenu.
15
bishop