web-dev-qa-db-fra.com

Django renvoie une erreur 403 lors de l'envoi d'une POST demande

lorsque j'utilise le code Python suivant pour envoyer une demande POST à mon site Web Django, je reçois le message d'erreur 403: Forbidden.

url = 'http://www.sub.domain.com/'
values = { 'var': 'test' }

try:
    data = urllib.urlencode(values, doseq=True)
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    the_page = response.read()
except:
    the_page = sys.exc_info()
    raise

Lorsque j'ouvre un autre site Web, cela fonctionne correctement . Domain.com est également le site Web de Django, et cela fonctionne également correctement. ... Je pense que c'est le problème de configuration de Django. accès à mon script?

33
Djent

La vue que vous publiez comporte-t-elle un formulaire Django? Si oui, je me demande si cela donne une erreur de CSRF. Je pense que cela se manifeste par un 403. Dans ce cas, vous devez ajouter la balise {{csrf_token}}. Juste une pensée. 

26
Joe J

Regardez ici https://docs.djangoproject.com/en/dev/ref/csrf/#how-to-use-it .

Essayez de marquer votre vue avec @csrf_exempt. De cette façon, le middleware CSRF de Django ignorera la protection CSRF. Vous devrez également utiliser from Django.views.decorators.csrf import csrf_exempt. Voir: https://docs.djangoproject.com/en/dev/ref/csrf/#utilities

Veuillez noter qu'en désactivant la protection CSRF de votre vue, vous ouvrez une porte pour les attaques CSRF.

Si la sécurité est essentielle pour vous, envisagez d'utiliser @csrf_exempt suivi de @requires_csrf_token (voir: https://docs.djangoproject.com/en/dev/ref/csrf/#unprotected-view-needs-the-csrf-token ). Ensuite, dans votre script, transmettez ce jeton et le tour est joué.

45
bx2

La réponse est 403 car Django requiert un jeton csrf (inclus dans les données de publication) dans chaque demande POST que vous effectuez.

Il existe différentes manières de le faire, telles que:

L’acquisition du jeton à partir du cookie et de la méthode a été expliquée dans l’article Entrez la description du lien ici

ou

Vous pouvez y accéder depuis DOM en utilisant {{csrf_token}}, disponible dans le modèle.

Alors maintenant, en utilisant la deuxième méthode:

var post_data = {
  ...
  'csrfmiddlewaretoken':"{{ csrf_token }}"
  ...
}

$.ajax({
  url:'url',
  type:'POST'
  data:post_data,
  success:function(data){
    console.log(data);
  },
  error:function(error){
    console.log(error);
  }
});
3
Hiro

J'ai eu cette erreur lorsqu'un jeton d'authentification a expiré ou quand aucun jeton n'a été envoyé avec la demande. L'utilisation d'un jeton renouvelé a résolu le problème. 

curl -X POST -H "Authorization: Token mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

ou 

curl -X POST -H "Authorization: JWT mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

en fonction du type de jeton.

0
DevB2F

La documentation de Django fournit plusieurs moyens de s'assurer que les jetons CSRF sont inclus. Voir https://docs.djangoproject.com/fr/1.11/ref/csrf/ pour plus de détails.

0
polarise

Ou vous pouvez autoriser la permission de faire cette demande de publication. 

Remarque: doit être utilisé dans les cas où vous n'avez pas besoin d'authentifier les utilisateurs pour pouvoir poster quoi que ce soit sur notre serveur, par exemple lorsqu'un nouvel utilisateur s'enregistre pour la première fois

from rest_framework.permissions import AllowAny

class CreateUser(APIView):
    permission_classes = (AllowAny,)
    def post(self, request, format=None):
        return(Response("hi"))

Notez en outre que, si vous souhaitez que cette demande de publication forme un domaine différent (dans le cas où le recto de l'application est dans React ou angular et que le backend est dans Django), assurez-vous que l'ajout suivant dans le fichier de paramètres:

  1. Mettez à jour INSTALLED_APPS pour utiliser 'coreHeaders': 

    INSTALLED_APPS = [
    'corsheaders',
    ]

  2. Liste blanche votre domaine frontal en ajoutant ce qui suit au fichier de paramètres:

    CORS_Origin_WHITELIST = ( 'Localhost: 8080', )

0
Santosh Pillai