76

私は次のようなパラメータを投稿しようとします

 jQuery.ajax(
        {
            'type': 'POST',
            'url': url,
            'contentType': 'application/json',
            'data': "{content:'xxx'}",
            'dataType': 'json',
            'success': rateReviewResult 
        }
    );

Forbidden 403. CSRF verification failed. Request aborted. しかし、私が使用しているDjangoリターンは、'django.middleware.csrf.CsrfViewMiddleware'セキュリティを損なうことなくこの問題を防ぐ方法を見つけることができませんでした。

4

13 に答える 13

115

次の 2 つの方法で AJAX ポスト リクエストを作成できます。

  1. ビューに csrf トークンをチェックしないように指示します。@csrf_exemptこれは、次のようにdecorator を使用して実行できます。

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    def your_view_name(request):
        ...
    
  2. jQuery の場合、各 AJAX リクエストに csrf トークンを埋め込むには、次のようにします。

    $(function () {
        $.ajaxSetup({
            headers: { "X-CSRFToken": getCookie("csrftoken") }
        });
    });
    

    getCookie関数が Cookie から 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には、次のような Cookie にアクセスするためのプラグインがあります。

    // set cookie
    $.cookie('cookiename', 'cookievalue');
    // read cookie
    var myCookie = $.cookie('cookiename');
    // delete cookie
    $.cookie('cookiename', null);
    
于 2011-06-30T10:42:07.473 に答える
55

私が見つけた最も簡単な方法は{{csrf_token}}、データに値を含めることです。

jQuery.ajax(
    {
        'type': 'POST',
        'url': url,
        'contentType': 'application/json',
        'data': {
            'content': 'xxx',
            'csrfmiddlewaretoken': '{{ csrf_token }}',
        },
        'dataType': 'json',
        'success': rateReviewResult 
    }
);
于 2011-07-29T04:10:08.110 に答える
25

ダニエルが投稿したコードをどうするかを理解するのに少し時間がかかりました。しかし実際には、javascript ファイルの先頭に貼り付けるだけです。

私にとって、これまでのところ最良の解決策は次のとおりです。

  1. csrf.jsファイルを作成する

  2. コードcsrf.jsファイルに貼り付けます

  3. 必要なテンプレートでコードを参照する

    <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、拡張元のようなものがある場合は、そこからスクリプトを参照するだけで、残りのファイルを心配する必要はありません。私が理解している限り、これもセキュリティ上の問題を表すものではありません。

于 2012-04-30T15:29:18.593 に答える
4

昨日同じ問題が発生し、それを処理する簡単な方法があれば人々の助けになると思ったので、そのための jQuery プラグインjquery.djangocsrfを作成しました。すべてのリクエストに CSRF トークンを追加する代わりに、AjaxSend jQuery イベントにフックし、ヘッダーにクライアント Cookie を追加します。

使用方法は次のとおりです。

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 は常に Cookie にトークンを追加します{% 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 を使用しています。

于 2014-03-21T11:32:35.017 に答える
4

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',

});
于 2016-04-10T19:53:21.680 に答える
0

このようにするときは、タグの{% csrf_token %}内側にないことを確認してください。<form></form>次に、ここで説明したように、次のコードを 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) {
    // ...
});
于 2020-11-12T17:06:45.623 に答える
0

他の回答を読んだ後、誰かがまだ苦労している場合は、これを試してください:

   $.ajax({
            type: "POST",
            beforeSend: function (request)
            {
                request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}");
            },
            url: servlet_path,
            data : data,
            success : function(result) {
            console.log("Success!");
   }
});
于 2016-09-07T11:17:40.430 に答える