web-dev-qa-db-fra.com

Échec de CSRF: Jeton CSRF manquant ou incorrect

J'utilise Django 1.7 et Django-rest-framework.

J'ai créé une API qui me renvoie des données JSON en les mettant dans mon settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
    'DEFAULT_RENDERER_CLASSES': (
    #   'rest_framework.renderers.XMLRenderer',
    'rest_framework.renderers.JSONRenderer',
    #   'rest_framework.renderers.BrowsableAPIRenderer',
    )
}

Lorsque je passe des appels GET, toutes les données me sont renvoyées, mais lorsque j'essaie avec PUT/PATCH, je reçois:

--------Response Headers---------
Status Code: 403
Date: Wed, 29 Oct 2014 18:51:42 GMT
Vary: Cookie
Server: WSGIServer/0.1 Python/2.7.8
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
---------------------------------

--------Response Body-----------
{"detail": "CSRF Failed: CSRF token missing or incorrect."}
---------------------------------

Cela ne se produit que lorsque je suis connecté, si je suis anonyme, je peux correctement PUT/PATCH.

J'ai essayé avec @csrf_exempt et j'ai eu des erreurs, j'ai inclus le rest_framework.permissions.AllowAny dans le réglage ...

Je ne ai aucune idée de ce qui se passe. Quelqu'un sait-il quel est le problème?

32
Alex Lord Mordor

Lorsque vous utilisez SessionAuthentication , vous utilisez l'authentification de Django qui nécessite généralement la vérification de CSRF. Django REST Framework l'applique uniquement pour SessionAuthentication. Vous devez donc transmettre le jeton CSRF dans l'en-tête X-CSRFToken.

La Documentation Django fournit plus d'informations sur la récupération du jeton CSRF à l'aide de jQuery et son envoi dans des requêtes. Le jeton CSRF est enregistré sous la forme d'un cookie appelé csrftoken que vous pouvez récupérer à partir d'une réponse HTTP, qui varie en fonction de la langue utilisée.

Si vous ne pouvez pas récupérer le cookie CSRF, cela signifie généralement que vous ne devez pas utiliser SessionAuthentication. Je recommande de regarder dans TokenAuthentication ou OAuth 2.0 en fonction de vos besoins.

53
Kevin Brown

C’est ce que j’ai fait pour le résoudre. J’ai inclus le jeton CSRF dans le formulaire et jQuery/javascrip a obtenu le jeton CSRF comme celui-ci lorsque le document est chargé.

var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

le inclus sur les en-têtes jquery comme suit

 $.ajax({
            type: "POST",
            url: "/api/endpoint/",
            data: newEndpoint,
            headers:{"X-CSRFToken": $crf_token},
            success: function (newEnd) {
                console.log(newEnd);
                add_end(newEnd);
            },
            error: function () {
                alert("There was an error")
            }
        });
4
adoniswalker

J'ai eu un problème similaire, j'ai enveloppé mes URL sous la méthode csrf_exempt comme - 

from Django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
2
Suyash Soni

Obtenir le jeton du cookie:

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

var csrftoken = readCookie('csrftoken');

Envoyer un jeton dans la requête POST]:

  this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
            this.response = response.data;
        },
        function (response) {
            console.log(response);
        });
0
Ruslan
// USING AJAX TO UPDATE DATABASE THROUGH REST API
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});
0
Rajiv Sharma

J'ai eu un problème similaire dans lequel j'avais enveloppé les vues avec csrf_exempt et que je rencontrais toujours des erreurs. Il s'est avéré que je m'étais trompé d'URL, alors le problème a été résolu en un rappel "non trouvé" (qui n'était pas exempté de CSRF) et lançait donc une exception avant qu'on puisse me dire que l'URL était fausse.

0
kokociel

1- Rechercher l'en-tête du cookie

 enter image description here

2- Séparez le csrftoken du sessionid

3- Ajoutez le X-CSRFToken = {.. le csrftoken que vous avez extrait à l'étape 2 ..} voir ci-dessous

 enter image description here 4- Poster à nouveau

0
Feras

Lorsque vous hébergez le site Web de Django sur un serveur Apache, vous obtenez 

Échec de CSRF: Jeton CSRF manquant ou incorrect

Pour réparer ce fichier de configuration Apache ouvert - httpd.conf Ajoutez la ligne suivante:

WSGIPassAuthorization On
0
Rajiv Sharma