私はDjango 1.7およびDjango-rest-frameworkを使用しています。
これをsettings.py
に入れるJSONデータを返すAPIを作成しました
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
'DEFAULT_RENDERER_CLASSES': (
# 'rest_framework.renderers.XMLRenderer',
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
)
}
GET呼び出しを行うと、すべてのデータが返されますが、PUT/PATCHを試すと次のようになります。
--------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."}
---------------------------------
これは、ログインしているときにのみ発生します。匿名の場合は、正しくPUT/PATCHできます。
@csrf_exempt
を試しましたが、エラーが発生しました。設定にrest_framework.permissions.AllowAny
を含めました...
何が起こっているのか分かりません。誰が問題が何か知っていますか?
SessionAuthentication を使用している場合、通常CSRFをチェックする必要があるDjangoの認証を使用しています。 Django RESTフレームワークはSessionAuthentication
に対してのみこれを強制するため、X-CSRFToken
ヘッダーでCSRFトークンを渡す必要があります。
Django documentation は、jQueryを使用してCSRFトークンを取得し、リクエストで送信することに関する詳細情報を提供します。 CSRFトークンはcsrftoken
というCookieとして保存され、HTTP応答から取得できます。これは、使用されている言語によって異なります。
CSRF Cookieを取得できない場合、これは通常SessionAuthentication
を使用してはならないという兆候です。必要に応じて、 TokenAuthentication または OAuth 2. を調べることをお勧めします。
これは私がそれを解決するためにしたことです、フォームにcsrfトークンを含め、jquery/javascripを使用すると、ドキュメントがロードされたときにこのようなcsrfトークンを取得しました
var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');
次のようにjqueryヘッダーに含まれています
$.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")
}
});
私たちはこの問題を抱えていましたが、それはポストマンのせいでした。ヘッダーで渡されなかったcsrftoken
およびsessionid
のデフォルト値を自動的に送信していました。このチュートリアルに従うと、問題の修正に役立ちました: https://avilpage.com/2019/02/Django-tips-csrf-token-postman-curl.html
同様の問題が発生しました。URLをcsrf_exempt
メソッド-
from Django.views.decorators.csrf import csrf_exempt
url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
// 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);
}
}
});
ビューをcsrf_exempt
でラップしても同様の問題が発生しましたが、それでもエラーが発生していました。 URLが間違っていることが判明したため、「見つからない」コールバック(CSRFを免除されていない)に解決されたため、URLが間違っていると通知される前に例外をスローしていました。
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');
ヘッダーでトークンを送信POST request:
this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
this.response = response.data;
},
function (response) {
console.log(response);
});
ホストDjango Apacheサーバー上のWebサイト。TokenAuthenticationおよびSessionAuthenticationを使用したDjando restフレームワークは、
CSRF失敗:CSRFトークンが欠落しているか、正しくありません
このオープンApache設定ファイルを修正するには-httpd.conf次の行を追加します。
WSGIPassAuthorization On