4

AoA 私は Django を初めて使用します。POST からデータを取得しようとしていますが、エラー CSRF cookie が設定されていません。Google で解決策を見つけようと多くのことを試みましたが、Google 経由でもスタックオーバーフローを試みましたが、失敗しました

ここにコードがあります

ビュー.py

    from django.http import HttpResponse
    from django.template.loader import get_template
    from django.template import Context
    from django.template import RequestContext
    from django.core.context_processors import csrf
    from django.shortcuts import render_to_response

def search_Post(request):
    if request.method == 'POST':
            c = {}
        c.update(csrf(request))
        # ... view code here
                return render_to_response("search.html", c)

def search_Page(request):
    name='Awais you have visited my website :P'
    t = get_template('search.html')
    html = t.render(Context({'name':name}))
    return HttpResponse(html)

HTMLファイル

<p>
          {{ name }}
            <form method="POST" action="/save/">
              {% csrf_token %}
              <textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
              <input type="submit" value="Save Page"/>
            </form>
       <div>  Cant figure out any solution! :( </div>

 </p>

url.py

 url(r'^home/$', 'contacts.views.home_Page'),
 url(r'^save/$', 'contacts.views.search_Post'),
 url(r'^edit/$', 'contacts.views.edit_Page'),
 url(r'^search/$', 'contacts.views.search_Page'),

設定.py

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.csrf',
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.request',
    'django.contrib.messages.context_processors.messages'
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
4

5 に答える 5

8

私は同じ問題を抱えていましたが、ビューにensure_csrf_cookie デコレータを追加することで解決しました:

 from django.views.decorators.csrf import ensure_csrf_cookie
 @ensure_csrf_cookie
 def yourView(request):
     #...

ブラウザのCookieにcsrftokenを設定し、このようにajaxを作成できます

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));
}
$.ajaxSetup({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
    }
});
$.ajax({
        url: url,
        type: type,
        async: async,
        data: data,
        error: function (e) {},
        success: function (data) {
                returnFunction(data);
            }
    });
于 2014-05-21T15:23:46.827 に答える
5

両方の手段を使用して、CSRF トークンをテンプレート プロセッサに渡します

c = {}
c.update(csrf(request))

およびRequestContext は、1 つあれば十分ですが、docs を参照してください。しかし、「POST」リクエストを処理するために、間違った場所で使用しています。これらのリクエストは、通常、ブラウザがフォームに入力し、結果を取得したいときに送信されます。

ブラウザは、サーバーに GET リクエストを送信する home.html をレンダリングします。

t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)

あなたのコードの一部。そして、csrfトークンを渡す手段を使用しません。したがって、テンプレート プロセッサget_template().render()が呼び出されると、そのコンテキストにトークンがないため、テンプレートの {% csrf_token %} コードを単純に無視します。RequestContextしたがって、ビューの t.render(...) 部分で使用するか、cそこに dict を渡す必要があります。

ブラウザ ウィンドウで生成されたフォームを調べて確認できます。

アップデート

の後にseetings.pyコンマを追加する'django.core.context_processors.csrf'と、現在のように、文字列を連結するだけです。

次のようにする必要があります。

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.csrf',
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
于 2013-10-25T20:43:23.927 に答える
1

レンダリングするリクエストを渡すのを忘れたようです

Django には特別な Context クラス django.template.RequestContext が付属しており、通常の django.template.Context とは少し異なる動作をします。最初の違いは、最初の引数として HttpRequest を取ることです。例えば:

これらに加えて、RequestContext は常に django.core.context_processors.csrf を使用します。これは、admin および他の contrib アプリで必要とされるセキュリティ関連のコンテキスト プロセッサであり、偶発的な構成ミスの場合に備えて、意図的にハードコードされており、TEMPLATE_CONTEXT_PROCESSORS 設定によってオフにすることはできません。

必要なものは次のとおりです

t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))

よろしければ、ここでdjangoドックを確認できます https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

于 2013-10-25T20:40:09.813 に答える
1

HTML の修正から始めます ( =を忘れました):

<form method="POST" action="/search/save">
{% csrf_token %}
<textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
<input type="submit" value="Save Page"/>
</form>

また:

def home_Page(request):
    #if request.method == 'GET':
    name='Awais you have visited my website :P'
    if request.method == 'POST':
        #name = request.POST.get('content')
        return render_to_response("search.html", {}, context_instance=RequestContext(request))

    return render_to_response("home.html", {'name':name}, context_instance=RequestContext(request))
于 2013-10-25T20:44:33.230 に答える