Comment pouvez-vous déboguer une demande CORS avec cURL?

300

Comment pouvez-vous déboguer des requêtes CORS en utilisant cURL? Jusqu'à présent, je n'ai trouvé aucun moyen de "simuler" la demande de contrôle en amont.

themihai
la source

Réponses:

496

Voici comment vous pouvez déboguer les demandes CORS à l'aide de curl.

Envoi d'une demande CORS régulière à l'aide de cUrl:

curl -H "Origin: http://example.com" --verbose \
  https://www.googleapis.com/discovery/v1/apis?fields=

Le -H "Origin: http://example.com"drapeau est le domaine tiers faisant la demande. Remplacez quel que soit votre domaine.

L' --verboseindicateur imprime la réponse entière afin que vous puissiez voir les en-têtes de demande et de réponse.

L'URL que j'utilise ci-dessus est un exemple de demande à une API Google qui prend en charge CORS, mais vous pouvez la remplacer par l'URL que vous testez.

La réponse doit inclure l'en- Access-Control-Allow-Origintête.

Envoi d'une demande de contrôle en amont à l'aide de cUrl:

curl -H "Origin: http://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: X-Requested-With" \
  -X OPTIONS --verbose \
  https://www.googleapis.com/discovery/v1/apis?fields=

Cela ressemble à la demande CORS régulière avec quelques ajouts:

Les -Hdrapeaux envoient des en-têtes de demande de contrôle en amont supplémentaires au serveur

L' -X OPTIONSindicateur indique qu'il s'agit d'une demande HTTP OPTIONS.

Si la demande de contrôle en amont aboutit, la réponse doit inclure les en Access-Control-Allow-Origin- têtes de réponse Access-Control-Allow-Methodset Access-Control-Allow-Headers. Si la demande de contrôle en amont n'a pas abouti, ces en-têtes ne devraient pas apparaître ou la réponse HTTP ne sera pas 200.

Vous pouvez également spécifier des en-têtes supplémentaires, tels que User-Agent, à l'aide de l' -Hindicateur.

monsur
la source
2
cette page ne semble renvoyer aucun en-tête CORS, est-ce exact?
Janus Troelsen
1
Pour afficher les en-têtes réels, vous devez ajouter l' --verboseoption, comme mentionné ci-dessus.
monsur
10
ou --head:curl -H "Origin: http://example.com" --head https://www.googleapis.com/discovery/v1/apis\?fields\=
John Bachir
2
Utilisez --include pour voir les en-têtes.
Mika Tuupola
7
Dans le cas de S3, les en-têtes correspondants ne sont ajoutés que si la méthode appropriée est donnée, vous pouvez le faire en utilisant curl -H "Access-Control-Request-Method: GET" -H "Origin: http://example.com" -I https://s3.amazonaws.com/your-bucket/file.
Joscha
52

Réponse mise à jour qui couvre la plupart des cas

curl -H "Access-Control-Request-Method: GET" -H "Origin: http://localhost" --head http://www.example.com/
  1. Remplacez http://www.example.com/ par l'URL que vous souhaitez tester.
  2. Si la réponse inclut, Access-Control-Allow-*votre ressource prend en charge CORS.

Justification de la réponse alternative

Je google cette question de temps en temps et la réponse acceptée n'est jamais ce dont j'ai besoin. D'abord, il imprime le corps de la réponse qui est beaucoup de texte. Ajout de --headsorties uniquement aux en-têtes. Deuxièmement, lors du test des URL S3, nous devons fournir un en-tête supplémentaire -H "Access-Control-Request-Method: GET".

J'espère que cela vous fera gagner du temps.

Vilius Paulauskas
la source
2
si je recourbe sans définir l'origine et que je peux récupérer la réponse et les en-têtes (y compris l'en-tête de contrôle d'accès-autoriser l'origine), cela signifie-t-il que j'ai configuré mon CORS de manière incorrecte? curl -X GET ' endpoint.com ' -H 'Cache-Control: no-cache' --head
Jun711
le même @Jun
Lukas Lukac
1
Cela repose sur la --headcréation de curl pour imprimer les en-têtes, mais aussi sur curl pour faire une HEADdemande plutôt que sur a GET. Selon ce que vous testez, vous voudrez peut-être faire une GETdemande. Vous pouvez le faire en ajoutant --IXGET.
Aidan Fitzpatrick
2
N'est-ce pas à l'envers? L'origine ne devrait-elle pas plutôt être example.com?
Dustin Ingram
4

Le script bash "corstest" ci-dessous fonctionne pour moi. Il est basé sur Jun commentaire ci-dessus.

usage

URL corstest [-v]

exemples

./corstest https://api.coindesk.com/v1/bpi/currentprice.json
https://api.coindesk.com/v1/bpi/currentprice.json Access-Control-Allow-Origin: *

le résultat positif est affiché en vert

./corstest https://github.com/IonicaBizau/jsonrequest
https://github.com/IonicaBizau/jsonrequest does not support CORS
you might want to visit https://enable-cors.org/ to find out how to enable CORS

le résultat négatif est affiché en rouge et bleu

l'option -v affichera les en-têtes de boucles complètes

corstest

#!/bin/bash
# WF 2018-09-20
# https://stackoverflow.com/a/47609921/1497139

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}


#
# show the usage
#
usage() {
  echo "usage: [-v] $0 url"
  echo "  -v |--verbose: show curl result" 
  exit 1 
}

if [ $# -lt 1 ]
then
  usage
fi

# commandline option
while [  "$1" != ""  ]
do
  url=$1
  shift

  # optionally show usage
  case $url in      
    -v|--verbose)
       verbose=true;
       ;;          
  esac
done  


if [ "$verbose" = "true" ]
then
  curl -s -X GET $url -H 'Cache-Control: no-cache' --head 
fi
origin=$(curl -s -X GET $url -H 'Cache-Control: no-cache' --head | grep -i access-control)


if [ $? -eq 0 ]
then
  color_msg $green "$url $origin"
else
  color_msg $red "$url does not support CORS"
  color_msg $blue "you might want to visit https://enable-cors.org/ to find out how to enable CORS"
fi
Wolfgang Fahl
la source
l'ajout de l'en-tête Origin le rendrait meilleur, par exemple. -H 'origine: mydomain.xyz '
Bas
3

On dirait que cela fonctionne:

curl -I http://example.com

Recherchez Access-Control-Allow-Origin: *dans les en-têtes renvoyés

MalcolmOcean
la source
3
N'oubliez pas que *cela ne fonctionne pas si des informations d'identification telles qu'un cookie doivent être présentées avec la demande d'API. Dans ce cas, le FQDN est également requis dans la Access-Control-Allow-Originréponse Access-Control-Allow-Credentials: true. Les demandes avec accréditation n'ont pas été spécifiées comme une exigence par OP, donc *fonctionne pour toutes les demandes non authentifiées.
GameSalutes