장고의 AJAX를 통해 매개 변수를 게시하는 동안 "CSRF 토큰 누락 또는 부정확"
다음과 같은 매개 변수를 게시하려고 합니다.
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
로 .Forbidden 403. CSRF verification failed. Request aborted.
사용중입니다'django.middleware.csrf.CsrfViewMiddleware'
보안을 훼손하지 않으면서 이 문제를 예방할 수 있는 방법을 찾을 수 없었습니다
AJAX 포스트 요청은 두 가지 방법으로 할 수 있습니다.
보기에 crf 토큰을 확인하지 말라고 하는 것입니다.은 데코레이터다를 하여 할 수.
@csrf_exempt
과 같이:,:from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_view_name(request): ...
각 AJAX 요청에 crf 토큰을 내장하는 방법은 다음과 같습니다.
$(function () { $.ajaxSetup({ headers: { "X-CSRFToken": getCookie("csrftoken") } }); });
서.
getCookie
함수는 쿠키에서 crf 토큰을 검색합니다.저는 다음과 같은 구현을 사용합니다.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
}
);
다니엘이 올린 코드를 어떻게 해야 하는지 이해하는 데 시간이 좀 걸렸습니다.하지만 실제로 자바스크립트 파일의 처음에 붙여넣기만 하면 됩니다.
지금까지 가장 좋은 해결책은 다음과 같습니다.
만들기
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}}');
}
}
});
한 경우 만 X-CSRFToken
는 ajax에 csrftoken
. JQuery는 플러그인 없이(어떤 이유에서인지) 쿠키를 수행하지 않습니다.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
그리고 최소한의 코드 변경은 다음과 같습니다.
$.ajax({
headers: { "X-CSRFToken": $.cookie("csrftoken") },
...
});
js를 템플릿에 포함하지 않을 경우 플러그인이 없는 가장 빠른 솔루션은 다음과 같습니다.
.<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
에서 script.js합니다를 합니다.csrfmiddlewaretoken
당신의 안으로data
사전:
$.ajax({
type: 'POST',
url: somepathname + "do_it/",
data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
success: function() {
console.log("Success!");
}
})
를와 간단합니다.data: {csrfmiddlewaretoken: '{{ 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" );
템플릿이 다음을 사용할 경우 항상 쿠키에 토큰을 추가합니다.{% 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')
참고: 장고 1.6.2를 사용하고 있습니다.
모든 답변에 감사드립니다.저는 장고 1.5.1을 사용하고 있습니다.파티에 좀 늦었지만, 이만 가보겠습니다.
장고 프로젝트에 대한 링크가 매우 유용하다는 것을 알았지만, 아약스에 전화를 걸 때마다 추가 자바스크립트 코드를 포함시킬 필요는 없었습니다.
jerrykan의 응답은 매우 간결하고, 그렇지 않으면 일반적인 Ajax call에 한 줄만 추가하기 때문에 좋습니다.장고 템플릿 태그를 사용할 수 없는 상황에 대한 그의 의견 아래에 있는 의견에 대해, DOM에서 crf 미들웨어 토큰을 로드하는 것은 어떨까요?
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); }
});
편집 2016년 3월
지난 몇 년간 이 문제에 대한 저의 접근 방식이 바뀌었습니다.아래 코드(Django documents에서)를 main.js 파일에 추가하여 모든 페이지에 로드합니다.작업이 완료되면 ajax와의 CSRF 토큰에 대해 다시 걱정할 필요가 없습니다.
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');
포함하다x-csrftoken
요청한 헤더:
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',
});
다른 답변을 읽은 후에도 여전히 어려움을 겪고 있는 사람이 있다면 다음을 시도해 보십시오.
$.ajax({
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}");
},
url: servlet_path,
data : data,
success : function(result) {
console.log("Success!");
}
});
이런 식으로 할 때는 그러지 말아 주세요.{% csrf_token %}
내부에<form></form>
tags. 그러면 여기 설명된 것처럼 javascript에 다음 코드를 추가합니다.
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// 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;
}
const csrftoken = getCookie('csrftoken');
// using js fetch
// https://docs.djangoproject.com/en/3.1/ref/csrf/#setting-the-token-on-the-ajax-request
const request = new Request(
/* URL */,
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
mode: 'same-origin' // Do not send CSRF token to another domain.
}).then(function(response) {
// ...
});
여기에 두고 싶은 것은 만약GET
사용 사례에서 작동합니다. 그러면 CSRF 토큰이 필요하지 않습니다.나의 사용 사례를 위해, 사용하기GET
괜찮았습니다.
html
<form action="">
{% csrf_token %}
</form>
JS
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const request = new Request(
'url_here',
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
// mode: 'same-origin' optinal // Do not send CSRF token to another domain.
}).then(function(response) {
console.log(response);
});
</script>
내 실수에 대한 요약으로:
- 요청 내용 유형을 설정하는 것을 잊지 마십시오.
- crf 값을 가져옵니다.
- 템플릿
{{ csrf_token }}
- 쿠키는 장고 사이트에서 스니펫을 사용합니다.
NB. 기본 쿠키 이름은
csrftoken
, 하지만 에 의해 압도될 수 있습니다.CSRF_COOKIE_NAME
세팅- 쿠키에 액세스할 수 없는 경우 DOM(CSRF_USE_SSESS 또는 CSRF_COOKIE_HTTP ONLY를 True로 설정)
문서.querySelector('[name= csrfmiddlewaretoken])" 값;
- 템플릿
- 요청 헤더를 설정합니다. XMLHttpRequest를 사용하고 있습니다.
const Http = new XMLHttpRequest();
Http.setRequestHeader("X-CSRFToken", CSRF_VALUE);
Http.setRequestHeader("X_CSRFTOKEN", CSRF_VALUE);
헤더 이름은 다음과 같이 관리됩니다.
CSRF_HEADER_NAME
설정, 기본값은HTTP_X_CSRFTOKEN
.
그러나: "서버에서 수신한 헤더 이름은 모든 문자를 대문자로 변환하고 하이픈을 밑줄로 바꾸고 이름에 'HTTP_' 접두사를 추가하여 정규화됩니다." src.
그래서 만약에 설정을 해주시면.HTTP_X_CSRFTOKEN
헤더, 장고는 그것을 다음으로 변환할 것입니다.HTTP_HTTP_X_CSRFTOKEN
입니다를 입니다.CSRF missed
오류를 범실.
Http.setRequestHeader("X-CSRFToken", csrftoken); // This worked
Http.setRequestHeader("X-CSRFTOKEN", csrftoken); // Also this
Http.setRequestHeader("HTTP-X-CSRFToken", csrftoken); // Not working
Http.setRequestHeader("HTTP_X_CSRFTOKEN", csrftoken); // Not Working
Http.setRequestHeader("X_CSRFTOKEN", csrftoken); // Not working !!
에서 브라우저 url url 의 ajax와 않음
127.0.0.1
&localhost
똑같지 않아요!!data.append("csrfmiddlewaretoken", csrftoken);
제가 알기로는 요청서에.
언급URL : https://stackoverflow.com/questions/6506897/csrf-token-missing-or-incorrect-while-post-parameter-via-ajax-in-django
'programing' 카테고리의 다른 글
사파리 페이지가 iOS 렌더링을 중단하는 이유는 무엇입니까? (0) | 2023.10.02 |
---|---|
서버 A(Master로 생각하고 있음)에서 서버 B로 생성된 binlog 파일로 MYSQL 복제를 설정할 수 있습니까? (0) | 2023.10.02 |
MySQL 열 유형 "TIMESTamp"에는 "NOT NULL DEFAULT CURRENT_TIMESTamp ON UPDATE CURRENT_TIMESTamp"가 함축적으로 포함되어 있습니다. (0) | 2023.09.27 |
깃, 머큐리얼, 바자의 상대적 강점과 약점은? (0) | 2023.09.27 |
Android Spinner : 아이템 회피초기화 중에 선택한 호출 (0) | 2023.09.27 |