簡體   English   中英

禁止(403)CSRF驗證失敗。 請求中止。 即使使用{%csrf_token%}

[英]Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}

我正在嘗試在django中進行登錄,但出現此錯誤,我檢查了CSRF文檔,但對我來說沒有任何用處。

這是HTML:

<body>
  <section class="container">
    <div class="login">
      <h1>Login to Web App</h1>

      {% if form.errors %}
        <p class="error">Lo sentimos, la combinacion de usuario y contrasena no es correcta!</p>
      {% endif %}  

      <form action="/accounts/auth/" method="post">
      {% csrf_token %}  
      <input type='hidden' name='csrfmiddlewaretoken' value='randomchars'/>

        <p><input name="username" type="text" name="login" value="" placeholder="Username"></p>

        <p><input name="password" type="password" name="password" value="" placeholder="Password"></p>

        <p class="submit"><input type="submit" name="commit" value="Login"></p>
      </form>
    </div>
</body>

就像您在上面看到的那樣,我使用了{%csrf_token%},並且在已安裝的應用程序中有“ django.middleware.csrf.CsrfViewMiddleware”。

我的看法是:

from django.http import HttpResponse,HttpResponseRedirect
from django.template.loader import get_template 
from django.template import Context
from datetime import datetime
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf

from models import *
from django.shortcuts import get_object_or_404
from forms import *
from django.template.context import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login

def login(request):
    c = {}
    c.update(csrf(request))
    return render_to_response('login.html', c)    


def auth_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        auth.login(request.user)
        return HttpResponse('/accounts/loggedin') 
    else:
        return HttpResponse('/accounts/invalid')

我重定向到另一個我不使用{%csrf_token%}的HTML文件。

理論


要使csrf保護起作用,需要做一些事情(請參閱docs ):

  1. 您的瀏覽器必須接受服務器中的Cookie
  2. 確保您的settings.py已將“ django.middleware.csrf.CsrfViewMiddleware'作為中間件包括在內(或者在要保護的特定視圖上使用裝飾器csrf_protect())
  3. 確保將csrf令牌從django.core.context_processors.csrf傳遞到上下文管理器。

加載頁面時,請使用喜歡的瀏覽器查看頁面源。 不要打開模板html文件,請打開指向包含表單的視圖的URL。 查看放置{% csrf_token %} 如果您看到類似

<input type='hidden' name='csrfmiddlewaretoken' value="jdwjwjefjwdjqwølksqøwkop2j3ofje" />

你應該沒事的。

另一方面,如果您看到NOTPROVIDED ,則在創建csrf令牌時出現了問題。 通過查看源代碼( context_processors.pycsrf.py ),我們可以找到以下內容:

  • 如果get_token(request)返回None,則csrf(request)返回{'csrf_token': 'NOTPROVIDED'}
  • get_token(request)返回request.META.get("CSRF_COOKIE", None)

我認為這意味着如果未成功創建cookie,它將返回None

固定


對您來說,這意味着您應該先更換

<form action="/accounts/auth/" method="post" {% csrf_token %}>

<form action="/accounts/auth/" method="post">
{% csrf_token %}
(...)
</form>

我們希望csrf字段位於<form>...</form> 內部 ,而不是<form> 內部 由於目前的代碼是,它將被轉換為

<form action="/accounts/auth/" method="post" <input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />>

我們希望

<form action="/accounts/auth/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />

之后-查看源代碼,看看是否可以找到csrf字段。 如果您能看到它,那么一切都應該在理論上起作用。

您還可以檢查瀏覽器(例如Chrome)中是否設置了csrf cookie,右鍵單擊網頁,然后選擇Insepect Element 選擇Resources選項卡,然后單擊cookie。 您應該在那里找到一個cookie名稱csrftoken

如果您仍然有問題,仔細檢查你的中間件元組settings.py並仔細檢查您的瀏覽器如上所述從服務器接受cookier。

清除瀏覽器緩存,然后重試。 也許它使用保存在緩存cookie中的CSRF令牌。

通過上述答案的補充,嘗試在視圖中添加以下行

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def somathing():
   return something

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM