source

Ajax POST 요청으로 인해 장고 CSRF 체크가 실패함

lovecheck 2023. 1. 12. 22:08
반응형

Ajax POST 요청으로 인해 장고 CSRF 체크가 실패함

제 AJAX 포스트를 통해 Django의 CSRF 보호 메커니즘을 준수할 수 있도록 도움을 받을 수 있습니다.여기 지시사항을 따르겠습니다.

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/

그 페이지에 있는 AJAX 샘플 코드를 그대로 복사했습니다.

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/ #syslog

나는 의 내용을 인쇄하는 경보를 발했다.getCookie('csrftoken')before xhr.setRequestHeader실제로 데이터가 입력되어 있습니다.토큰이 맞는지 확인하는 방법은 확실하지 않지만, 무언가를 찾아서 보내고 있다는 것은 고무적인 일입니다.

하지만 장고는 여전히 내 AJAX 포스트를 거부하고 있다.

다음은 내 JavaScript입니다.

$.post("/memorize/", data, function (result) {
    if (result != "failure") {
        get_random_card();
    }
    else {
        alert("Failed to save card data.");
    }
});

다음은 Django에서 볼 수 있는 오류입니다.

[2011년 2월 23일 22:08:29] "POST/memoryize/HTTP/1.1" 403 2332

내가 뭔가 놓친 게 분명해, 어쩌면 간단할지 모르지만 그게 뭔지 모르겠어.본 , 하는 것에 할 수 .csrf_exempt그것 생각하고 있습니다저는 그것을 시험해 보았습니다만, 가능하다면, 제 POST가 Django가 예상한 대로 동작하도록 하고 싶습니다.

도움이 될 경우를 대비해서 제 견해는 다음과 같습니다.

def myview(request):

    profile = request.user.profile

    if request.method == 'POST':
        """
        Process the post...
        """
        return HttpResponseRedirect('/memorize/')
    else: # request.method == 'GET'

        ajax = request.GET.has_key('ajax')

        """
        Some irrelevent code...
        """

        if ajax:
            response = HttpResponse()
            profile.get_stack_json(response)
            return response
        else:
            """
            Get data to send along with the content of the page.
            """

        return render_to_response('memorize/memorize.html',
                """ My data """
                context_instance=RequestContext(request))

답장 고마워요!

「 」를하고 있는 는,$.ajax함수는 '어울리지 않다'를 됩니다.csrf다음 중 하나:

$.ajax({
    data: {
        somedata: 'somedata',
        moredata: 'moredata',
        csrfmiddlewaretoken: '{{ csrf_token }}'
    },

진정한 솔루션

좋아요, 그 문제를 찾아냈어요.Javascript 코드(아래 제안)에 있습니다.

필요한 것은 다음과 같습니다.

$.ajaxSetup({ 
     beforeSend: function(xhr, settings) {
         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;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     } 
});

공식 문서에 게시된 코드 대신 https://docs.djangoproject.com/en/2.2/ref/csrf/를 참조하십시오.

동작 코드는 다음 Django 엔트리에서 가져옵니다.http://www.djangoproject.com/weblog/2011/feb/08/security/

따라서 일반적인 해결책은 "ajaxSend 핸들러 대신 ajaxSetup 핸들러를 사용"입니다.왜 효과가 있는지 모르겠어요.하지만 내겐 효과가 있어:)

이전 투고(응답 없음)

사실 저도 같은 문제를 겪고 있어요.

Django 1.2.5로 업데이트 한 후 발생 - Django 1.2.4에서 AJAX POST 요청 오류는 발생하지 않았습니다(AJAX는 보호되지 않았지만 정상적으로 작동했습니다).

OP와 마찬가지로 Django 설명서에 게재된 JavaScript 스니펫을 사용해 보았습니다.jQuery 1.5를 사용하고 있습니다."django.middleware.csrf"도 사용하고 있습니다.CsrfViewMiddleware" 미들웨어.

미들웨어 코드를 따르려고 했는데, 이 코드에서는 실패합니다.

request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')

그리고 나서.

if request_csrf_token != csrf_token:
    return self._reject(request, REASON_BAD_TOKEN)

이 "if"는 "request_syslogf_syslog"가 비어있기 때문에 true입니다.

기본적으로 헤더가 설정되지 않았음을 의미합니다.이 JS 회선에 문제가 있습니까?

xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

?

자세한 내용을 알려주시면 문제 해결에 도움이 될 것입니다.

jQuery 코드에 다음 행을 추가합니다.

$.ajaxSetup({
  data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

다 했어요.

이 문제는 django가 쿠키의 값이 폼 데이터의 일부로 반환될 것으로 예상하기 때문입니다.이전 답변의 코드는 javascript를 받아 쿠키 값을 찾아 폼 데이터에 넣는 것입니다.그것은 기술적인 관점에서 그것을 하는 멋진 방법이지만, 조금 장황해 보인다.

예전에는 javascript를 받아 토큰 값을 포스트 데이터에 넣는 방법으로 간단하게 했습니다.

템플릿에서 {% csrf_token %}을(를) 사용하면 값을 전달하는 숨김 양식 필드가 출력됩니다.단, {{csrf_token}}을(를) 사용하면 토큰의 베어값만 얻을 수 있으므로 javascript에서 이렇게 사용할 수 있습니다.

csrf_token = "{{ csrf_token }}";

그런 다음 필요한 키 이름을 해시 내에 포함시키고 데이터로서 Ajax 콜에 송신할 수 있습니다.

{% csrf_token %}을 "html "에 <form></form>

는 다음과 같이 해석됩니다.

<input type='hidden' name='csrfmiddlewaretoken' value='Sdgrw2HfynbFgPcZ5sjaoAI5zsMZ4wZR' />

JS에서 이렇게 그리핑하면 어떨까요?

token = $("#change_password-form").find('input[name=csrfmiddlewaretoken]').val()

POST를 실시해, 다음과 같이 패스합니다.

$.post( "/panel/change_password/", {foo: bar, csrfmiddlewaretoken: token}, function(data){
    console.log(data);
});

논쿼리 답변:

var csrfcookie = function() {
    var cookieValue = null,
        name = 'csrftoken';
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
};

사용방법:

var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('X-CSRFToken', csrfcookie());
request.onload = callback;
request.send(data);

JS를 하는 방법에 하지 않은 것 .X-CSRFToken 와 "" 입니다.{{ csrf_token }}DOM을

var xhttp = new XMLHttpRequest();
xhttp.open("POST", url, true);
xhttp.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
xhttp.send();

JS 없이 폼이 Django에 올바르게 투고되면 csrf 토큰의 해킹이나 지저분한 전달 없이 Ajax로 점진적으로 강화할 수 있을 것입니다.전체 폼을 시리얼화하면 숨겨진 CSRF 필드를 포함한 모든 폼필드가 자동으로 선택됩니다.

$('#myForm').submit(function(){
    var action = $(this).attr('action');
    var that = $(this);
    $.ajax({
        url: action,
        type: 'POST',
        data: that.serialize()
        ,success: function(data){
            console.log('Success!');
        }
    });
    return false;
});

저는 이것을 Django 1.3+와 jQuery 1.5+로 테스트했습니다.이것은 분명히 Django 앱뿐만 아니라 어떤 HTML 폼에서도 동작합니다.

받아들여진 대답은 아마도 속임수일 것이다.Django 1.2.4와 1.2.5의 차이는 AJAX 요구에 대한 CSRF 토큰 요건입니다.

이 문제는 Django 1.3에서 발생했는데 CSRF cookie가 처음부터 설정되지 않았기 때문입니다.장고는 꼭 해야 할 때가 아니면 쿠키를 세팅하지 않을 것이다.따라서 Django 1.2.4에서 실행되는 독점 사이트 또는 대규모 Ajax 사이트에서는 클라이언트에 토큰이 전송되지 않을 가능성이 있으며, 그 토큰을 필요로 하는 업그레이드로 인해 403 오류가 발생합니다.

이상적인 수정 방법은 http://docs.djangoproject.com/en/dev/ref/contrib/csrf/ #page-uses-filename-without-filename-filename-form입니다.
수 있는 를 기다려야 할 것입니다.

편집

또한 최신 Django 문서는 jQuery 1.5의 버그를 기록하고 있으므로 Django 권장 코드인 https://docs.djangoproject.com/en/dev/ref/csrf/#debug와 함께 1.5.1 이후를 사용하고 있는지 확인하십시오.

파이어폭스 파이어버그아약스.★★★★★★★★★★★★★★★★ DEBUG=True응답으로 멋진 django 오류 페이지가 표시되고 콘솔 탭에서 ajax 응답의 렌더링된 html도 볼 수 있습니다.

그러면 뭐가 잘못됐는지 알 수 있을 거예요.

현재 답변 어디에도 기재되어 있지 않기 때문에 js를 템플릿에 포함하지 않는 경우 가장 빠른 해결책은 다음과 같습니다.

놓다를 <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>script에 "script.disc" 파일을 합니다.csrfmiddlewaretoken의 에 your에data파일 : "Dictionary" :

$.ajax({
            type: 'POST',
            url: somepathname + "do_it/",
            data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
            success: function() {
                console.log("Success!");
            }
        })

나는 조금 다르지만 비슷한 상황을 마주했을 뿐이다.고객님의 케이스에 대한 해결책이 될지는 100% 확신할 수 없지만, 적절한 쿠키 값 문자열로 POST 파라미터 'csrfmiddlewaretoken'을 설정하여 문제를 해결했습니다.이 문자열은 보통 Django의 템플릿시스템에 의해 홈 HTML 형식으로 반환되며, '{% csrf_token % }' 태그가 붙어 있습니다.저는 오래된 장고를 입어보지 않고 단지 장고 1.3으로 해결했을 뿐입니다.문제는 폼에서 Ajax를 통해 전송된 첫 번째 요청은 성공했지만, 두 번째 요청은 실패하여 헤더의 'X-CSRFToken'이 CSRF 토큰 값과 함께 올바르게 배치되어 있는데도 첫 번째 시도와 마찬가지로 403 상태가 되었다는 것입니다.이게 도움이 됐으면 좋겠다.

안부 전해요,

히로

이 js를 html 파일에 붙여넣을 수 있습니다.다른 js 함수 앞에 붙여주세요.

<script>
  // using jQuery
  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;
  }

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

  $(document).ready(function() {
    var csrftoken = getCookie('csrftoken');
    $.ajaxSetup({
      beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });
  });
</script>

Django를 사용한 간단한 Ajax 통화

26.10.199)
내 생각에 이것은 정답보다 훨씬 더 명확하고 간단하다.

@login_required
def some_view(request):
    """Returns a json response to an ajax call. (request.user is available in view)"""
    # Fetch the attributes from the request body
    data_attribute = request.GET.get('some_attribute')  # Make sure to use POST/GET correctly
    # DO SOMETHING...
    return JsonResponse(data={}, status=200)

urls.py

urlpatterns = [
    path('some-view-does-something/', views.some_view, name='doing-something'),
]

Ajax 콜

Ajax 콜은 매우 간단하지만 대부분의 경우 충분합니다.일부 값을 가져와 데이터 객체에 넣을 수 있습니다. 그런 다음 위의 보기에서 해당 이름을 통해 해당 값을 다시 가져올 수 있습니다.

csrftoken 함수는 django 문서에서 찾을 수 있습니다.기본적으로 복사하고 csrftoken 변수가 정의되도록 Ajax 콜 전에 렌더링해야 합니다.

$.ajax({
    url: "{% url 'doing-something' %}",
    headers: {'X-CSRFToken': csrftoken},
    data: {'some_attribute': some_value},
    type: "GET",
    dataType: 'json',
    success: function (data) {
        if (data) {
            console.log(data);
            // call function to do something with data
            process_data_function(data);
        }
    }
});

Ajax를 사용하여 현재 페이지에 HTML 추가

이것은 다소 주제에서 벗어났을 수도 있지만, 저는 이것을 거의 사용하지 않았습니다.또한 창 재배치 및 Javascript에서의 수동 html 문자열 작성을 최소화하는 좋은 방법입니다.

이것은 위와 매우 유사하지만 이번에는 현재 창을 새로고침하지 않고 응답에서 html을 렌더링합니다.

Ajax 호출에 대한 응답으로 수신되는 데이터로부터 어떤 종류의 html을 렌더링하는 경우, JsonResponse 대신 뷰에서HttpResponse를 반환하는 것이 더 쉬울 수 있습니다.이를 통해 쉽게 html을 만들 수 있으며, 이 html을 요소에 삽입할 수 있습니다.

# The login required part is of course optional
@login_required
def create_some_html(request):
    """In this particular example we are filtering some model by a constraint sent in by 
    ajax and creating html to send back for those models who match the search"""
    # Fetch the attributes from the request body (sent in ajax data)
    search_input = request.GET.get('search_input')

    # Get some data that we want to render to the template
    if search_input:
        data = MyModel.objects.filter(name__contains=search_input) # Example
    else:
        data = []

    # Creating an html string using template and some data
    html_response = render_to_string('path/to/creation_template.html', context = {'models': data})

    return HttpResponse(html_response, status=200)

보기용 html 생성 템플릿

creation_creating.syslogs

{% for model in models %}
   <li class="xyz">{{ model.name }}</li>
{% endfor %}

urls.py

urlpatterns = [
    path('get-html/', views.create_some_html, name='get-html'),
]

메인 템플릿과 에이잭스콜

데이터를 추가할 템플릿입니다.특히 이 예에서는 검색 입력과 검색 입력 값을 뷰로 전송하는 버튼이 있습니다.그런 다음 뷰는 요소 내에서 렌더링할 수 있는 검색과 일치하는 데이터를 표시하는 HttpResponse를 다시 보냅니다.

{% extends 'base.html' %}
{% load static %}
{% block content %}
    <input id="search-input" placeholder="Type something..." value="">
    <button id="add-html-button" class="btn btn-primary">Add Html</button>
    <ul id="add-html-here">
        <!-- This is where we want to render new html -->
    </ul>
{% end block %}

{% block extra_js %}
    <script>
        // When button is pressed fetch inner html of ul
        $("#add-html-button").on('click', function (e){
            e.preventDefault();
            let search_input = $('#search-input').val();
            let target_element = $('#add-html-here');
            $.ajax({
                url: "{% url 'get-html' %}",
                headers: {'X-CSRFToken': csrftoken},
                data: {'search_input': search_input},
                type: "GET",
                dataType: 'html',
                success: function (data) {
                    if (data) {
                        /* You could also use json here to get multiple html to
                        render in different places */
                        console.log(data);
                        // Add the http response to element
                        target_element.html(data);
                    }
                }
            });
        })
    </script>
{% endblock %}

제 경우 메인 서버에서 임시 서버로 복사한nginx 설정에 문제가 있었습니다.이 설정에서는 프로세스의 두 번째 서버에서는 필요 없는https를 무효로 합니다.

설정을 다시 동작시키기 위해서, 다음의 2 행을 코멘트 아웃 할 필요가 있었습니다.

# uwsgi_param             UWSGI_SCHEME    https;
# uwsgi_pass_header       X_FORWARDED_PROTO;

각 세션에 1개의 CSRF 토큰이 할당됩니다(즉, 로그인할 때마다).따라서 사용자가 입력한 데이터를 ajax 호출로 csrf_protect decorator에 의해 보호되는 함수로 전송하기 전에 호출되는 함수를 검색한 후 사용자로부터 데이터를 가져옵니다.예를 들어 사용자가 데이터를 입력하는 일부 템플릿이 렌더링되어야 합니다.그 템플릿은 어떤 함수에 의해 렌더링되고 있습니다.이 함수에서는 csrf = request와 같이 csrf 토큰을 얻을 수 있습니다.CUKIES['csrftoken'] 이제 해당 템플릿이 렌더링되는 컨텍스트 사전에서 이 csrf 값을 전달합니다.이 템플릿에 다음 행을 입력합니다.이제 javascript 함수로, Ajax 요청을 하기 전에 다음과 같이 적습니다.var csrf = $('#csrf').val() 이것은 템플릿에 전달된 토큰의 값을 선택하여 변수 csrf에 저장합니다.Ajax 콜을 발신할 때 투고 데이터에서도 다음 값을 전달합니다.csrf middle ware token : csrf

이는 django 형식을 구현하지 않아도 작동합니다.

사실 여기서 논리는 다음과 같습니다.요청에서 얻을 수 있는 토큰이 필요합니다.따라서 로그인 즉시 호출되는 함수를 파악하기만 하면 됩니다.이 토큰을 가지고 있으면 다른 Ajax 콜을 발행하여 가져오거나 Ajax에서 액세스할 수 있는 템플릿에 전달합니다.

디버깅을 시도하고 있는 사용자:

1) django csrf check (발송 예정)는 이쪽입니다.

2) 저 같은 경우에는settings.CSRF_HEADER_NAME는 'HTTP_X_CSRFTOKEN'으로 설정되어 있으며, AJAX 콜은 'HTTP_X_CSRF_TOKEN'이라는 이름의 헤더를 전송하고 있었기 때문에 동작하지 않았습니다.AJAX 콜 또는 django 설정에서 변경할 수 있습니다.

3) 서버측을 변경하는 경우는, 인스톨 장소의 django 를 검색해, 에 브레이크 포인트를 설정합니다.csrf middleware.사용하시는 경우virtualenv다음과 같습니다.~/.envs/my-project/lib/python2.7/site-packages/django/middleware/csrf.py

import ipdb; ipdb.set_trace() # breakpoint!!
if request_csrf_token == "":
    # Fall back to X-CSRFToken, to make things easier for AJAX,
    # and possible for PUT/DELETE.
    request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')

그리고 나서,csrf토큰은 요구에서 올바르게 발신됩니다.메타

4) 헤더 등을 변경할 필요가 있는 경우 - 설정 파일의 변수 변경

누군가 이 일을 하기 위해 악리를 가지고 씨름하고 있다면, 이것은 나에게 도움이 되었다.

import axios from 'axios';

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'

출처 : https://cbuelter.wordpress.com/2017/04/10/django-csrf-with-axios/

다음은 Django가 제공하는 간단한 솔루션입니다.

<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// set csrf header
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

// Ajax call here
$.ajax({
    url:"{% url 'members:saveAccount' %}",
    data: fd,
    processData: false,
    contentType: false,
    type: 'POST',
    success: function(data) {
        alert(data);
        }
    });
</script>

출처 : https://docs.djangoproject.com/en/1.11/ref/csrf/

Django 3.1.1을 사용하여 시도한 모든 솔루션에 실패했습니다.다만, POST 본문에 「csrfmiddlewaretoken」키를 추가하는 것으로 동작했습니다.전화 드린 내용은 다음과 같습니다.

$.post(url, {
  csrfmiddlewaretoken: window.CSRF_TOKEN,
  method: "POST",
  data: JSON.stringify(data),
  dataType: 'JSON',
});

HTML 템플릿에서 다음을 수행합니다.

<script type="text/javascript">
  window.CSRF_TOKEN = "{{ csrf_token }}";
</script>

업데이트 2022

CSRF 공격에서는 무고한 최종 사용자가 공격자에게 속아 의도하지 않은 웹 요구를 송신한다.

옵션 1

from django.views.decorators.csrf import csrf_exempt
from django.http.response import JsonResponse


@csrf_exempt
def commentDeletePost(request):
    if request.is_ajax() and request.method == 'POST':
        try:
            comment = Comment.objects.get(pk=request.POST['pk'])
            if comment.author != request.user:
                return JsonResponse({'e': 'Forbidden'}, status=403) 
            comment.delete()
            return JsonResponse({}, status=200)
        execpt Comment.DoesNotExist:
            return JsonResponse({'e': 'Not Found'}, status=404)

옵션 2

<div id="csrf">
    {% csrf_token %}
</div>
<script type="text/javascript">
    window.crud = {
        commentDelete: function(
            pk, 
            success,
            error, 
        ){
            $.ajax({
                headers: {'X-CSRFToken': document.getElementById('csrf').querySelector('input').value},
                type: "POST", 
                url: "{% url 'comment-delete-post' %}",
                data: {
                    pk: pk,
                }, 
                success: success, 
                error: error,
            })
        }, 
    }
</script>

두 가지 옵션에는 장점이 있습니다.첫 번째 옵션은 csrf 토큰을 폐기합니다.이것에 의해, csrf 공격으로부터 사이트가 보호되는 것은 아닙니다만, 유저는 같은 Ajax 기능을 사용해 복수의 요구를 송신할 수 있습니다.두 번째 옵션은 csrf 토큰을 한 번만 사용할 수 있기 때문에 사용자가 Ajax 요청을 하나만 보낼 수 있도록 제한하지만 더 안전합니다.저는 개인적으로 옵션 1을 선호합니다. 왜냐하면 Ajax는 다음과 같은 기능을 하기 때문입니다.like, star, unlike는 여러 개의 Ajax 콜을 필요로 하며 사용자 콜을 여러 번 허용하는 것은 위험한 함수가 아닙니다.

선택한 답변과 관련하여 선택한 답변에 추가하려고 합니다.

이 답변에서, 다음 솔루션과 관련하여.ajaxSetup(...) 장고 설정파이다

CSRF_USE_SESSIONS = True

그러면 선택한 Answer가 전혀 작동하지 않습니다.이 행을 삭제하거나 False로 설정하면 선택한 Answer의 솔루션을 구현할 때 도움이 됩니다.

흥미롭게도, 만약 당신이 당신의 장고 설정에서 다음을 설정한다면.화이

CSRF_COOKIE_HTTPONLY = True

이 변수는 선택한 응답 솔루션의 작동을 중지하지 않습니다.

다.CSRF_USE_SESSIONS ★★★★★★★★★★★★★★★★★」CSRF_COOKIE_HTTPONLY공식 Django doc https://docs.djangoproject.com/en/2.2/ref/csrf/ 에서 입수했습니다.

(댓글을 달 수 있는 담당자가 없기 때문에 답변을 투고합니다.)

나는 해결책을 가지고 있다.JS에는 두 가지 기능이 있습니다.쿠키를 처음 가져오는 경우(즉, csroken):

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;

}

두번째는 나의 아약스 기능이다.이 경우 로그인을 위한 것으로, 실제로는 아무것도 반환되지 않습니다.세션을 설정하기 위한 값을 전달하기만 하면 됩니다.

function LoginAjax() {


    //get scrftoken:
    const csrftoken = getCookie('csrftoken');

    var req = new XMLHttpRequest();
    var userName = document.getElementById("Login-Username");
    var password = document.getElementById("Login-Password");

    req.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {            
            //read response loggedIn JSON show me if user logged in or not
            var respond = JSON.parse(this.responseText);            
            alert(respond.loggedIn);

        }
    }

    req.open("POST", "login", true);

    //following header set scrftoken to resolve problem
    req.setRequestHeader('X-CSRFToken', csrftoken);

    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.send("UserName=" + userName.value + "&Password=" + password.value);
}

언급URL : https://stackoverflow.com/questions/5100539/django-csrf-check-failing-with-an-ajax-post-request

반응형