Django에서 AJAX를 통해 매개 변수를 게시하는 동안 "CSRF 토큰이 없거나 잘못되었습니다."
나는 다음과 같은 매개 변수를 게시하려고합니다.
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
그러나 Django는 Forbidden 403. CSRF verification failed. Request aborted.
내가 사용 'django.middleware.csrf.CsrfViewMiddleware'
하고 있으며 보안을 손상시키지 않고이 문제를 예방할 수있는 방법을 찾을 수 없습니다.
다음 두 가지 방법으로 AJAX 게시 요청을 할 수 있습니다.
보기에 csrf 토큰을 확인하지 않도록 지시합니다. 이것은 다음
@csrf_exempt
과 같이 decorator를 사용하여 수행 할 수 있습니다 .from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_view_name(request): ...
각 AJAX 요청에 csrf 토큰을 포함하려면 jQuery의 경우 다음과 같을 수 있습니다.
$(function () { $.ajaxSetup({ headers: { "X-CSRFToken": getCookie("csrftoken") } }); });
어디
getCookie
함수를 검색은 쿠키에서 토큰 CSRF. 다음 구현을 사용합니다.function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf(c_name + "="); if (c_start != -1) { c_start = c_start + c_name.length + 1; c_end = document.cookie.indexOf(";", c_start); if (c_end == -1) c_end = document.cookie.length; return unescape(document.cookie.substring(c_start,c_end)); } } return ""; }
또한 jQuery 에는 다음과 같은 쿠키에 액세스하기 위한 플러그인 이 있습니다.
// set cookie $.cookie('cookiename', 'cookievalue'); // read cookie var myCookie = $.cookie('cookiename'); // delete cookie $.cookie('cookiename', null);
내가 찾은 가장 간단한 방법 {{csrf_token}}
은 데이터에 값 을 포함하는 것입니다 .
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': {
'content': 'xxx',
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
'dataType': 'json',
'success': rateReviewResult
}
);
Daniel이 게시 한 코드로 무엇을해야하는지 이해하는 데 시간이 걸렸습니다 . 하지만 실제로해야 할 일은 자바 스크립트 파일의 시작 부분에 붙여 넣기 만하면됩니다.
나를 위해 지금까지 최고의 솔루션은 다음과 같습니다.
csrf.js
파일 생성붙여 넣기 코드를 에
csrf.js
파일필요한 템플릿의 코드를 참조하세요.
<script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
STATIC_PREFIX/js/csrf.js
내 파일 을 가리 킵니다. 실제로 STATIC_PREFIX
변수를 {% get_static_prefix as STATIC_PREFIX %}
.
고급 팁 : 템플릿을 사용 중이고 base.html
확장 위치 와 같은 것이 있다면 거기에서 스크립트를 참조 할 수 있으며 나머지 파일에서 더 이상 걱정할 필요가 없습니다. 내가 이해하는 한 이것은 보안 문제를 나타내지 않아야합니다.
간단하고 짧음
$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' }
});
또는
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", '{{csrf_token}}');
}
}
});
어제 같은 문제가 발생했고이를 처리하는 간단한 방법이 있다면 사람들에게 도움이 될 것이라고 생각했기 때문에 jquery.djangocsrf 라는 jQuery 플러그인을 작성했습니다 . 모든 요청에 CSRF 토큰을 추가하는 대신 AjaxSend jQuery 이벤트에 연결하고 헤더에 클라이언트 쿠키를 추가합니다.
사용 방법은 다음과 같습니다.
1- 포함 :
<script src="path/to/jquery.js"></script>
<script src="path/to/jquery.cookie.js"></script>
<script src="path/to/jquery.djangocsrf.js"></script>
2- 코드에서 활성화하십시오.
$.djangocsrf( "enable" );
Django는 템플릿이 {% csrf_token %}
. 템플릿에서 특수 태그를 사용하지 않더라도 항상 추가하려면 @ensure_csrf_cookie
데코레이터를 사용하세요 .
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def my_view(request):
return render(request, 'mytemplate.html')
참고 : 저는 Django 1.6.2를 사용하고 있습니다.
모든 답변에 감사드립니다. Django 1.5.1을 사용하고 있습니다. 파티에 좀 늦었지만 여기 간다.
I found the link to the Django project to be very useful, but I didn't really want to have to include the extra JavaScript code every time I wanted to make an Ajax call.
I like jerrykan's response as it is very succinct and only adds one line to an otherwise normal Ajax call. In response to the comments below his comment regarding situations when Django template tags are unavailable, how about loading up the csrfmiddlewaretoken from the DOM?
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
data: { 'csrfmiddlewaretoken': token },
dataType: 'json',
success: function(data) { console.log('Yippee! ' + data); }
});
EDIT March 2016
My approach to this issue over the past few years has changed. I add the code below (from the Django docs) to a main.js file and load it on every page. Once done, you shouldn't need to worry about the CSRF token with ajax again.
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]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
Include x-csrftoken
header in request:
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
beforeSend : function(jqXHR, settings) {
jqXHR.setRequestHeader("x-csrftoken", get_the_csrf_token_from_cookie());
},
data: data,
dataType: 'json',
});
For lack of a straight forward answer, you just have to add the header X-CSRFToken
to the ajax request which is in the cookie csrftoken
. JQuery doesn't do cookies (for some reason) without a plugin so:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
and the minimal code change is:
$.ajax({
headers: { "X-CSRFToken": $.cookie("csrftoken") },
...
});
The fastest solution without any plugins if you are not embedding js into your template is:
Put <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
before your reference to script.js file in your template, then add csrfmiddlewaretoken
into your data
dictionary:
$.ajax({
type: 'POST',
url: somepathname + "do_it/",
data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
success: function() {
console.log("Success!");
}
})
If you do embed your js into the template, it's as simple as: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}
If, after reading other answers, someone is still struggling please try this:
$.ajax({
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}");
},
url: servlet_path,
data : data,
success : function(result) {
console.log("Success!");
}
});
'IT Share you' 카테고리의 다른 글
C 프로그래밍 : 다른 함수 내부의 malloc () (0) | 2020.12.02 |
---|---|
자바 : 객체를 byte []로, byte []를 객체로 변환기 (도쿄 내각 용) (0) | 2020.12.02 |
ansible에서 ansible을 실행하는 사용자의 이름으로 변수를 얻으려면 어떻게해야합니까? (0) | 2020.12.02 |
Tmux 테두리가 줄 대신 xq로 표시됩니까? (0) | 2020.12.02 |
Console.Clear를 사용하여 전체 콘솔 대신 한 줄만 지울 수 있습니까? (0) | 2020.12.02 |