禁止(403)CSRF验证失败。请求中止。即使使用{%csrf_token%} [英] Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}

查看:320
本文介绍了禁止(403)CSRF验证失败。请求中止。即使使用{%csrf_token%}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在django中登录,但是我收到此错误,我查看了CSRF文档,对我而言无效。



这是HTML: / p>

 < body> 
< section class =container>
< div class =login>
< h1>登录到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 =usernametype =textname =loginvalue =placeholder =Username>< / p>

< p>< input name =passwordtype =passwordname =passwordvalue =placeholder =Password>< / p>

< p class =submit>< input type =submitname =commitvalue =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上下文
from datetime import datetime
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib从django.core.context_processors导入auth
导入csrf
$ b从模型导入*
从django来自django.template.context的request.object_or_404
从django.template.context导入RequestContext
从django.contrib.auth.decorators导入login_required
从django.contrib.auth导入验证,

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


def auth_view(request):
username = request.POST ['username']
password = request。 POST ['password']
user = authenticate(username = username,password = password)
如果用户不是None:
auth.login(request.user)
return HttpResponse ('/ accounts / loggedin')
else:
return HttpResponse('/ accounts / invalid')

我重定向到其他HTML文件,我不使用{%csrf_token%}。

解决方案

理论






需要几件事才能使csrf保护工作(请查看 docs ):


  1. 您的浏览器必须接受来自您服务器的Cookie

  2. 确保您具有' django.middleware.csrf.CsrfViewMiddleware'包括为m您的 settings.py 中的iddleware(或者对您想要保护的特定视图使用装饰器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.py csrf.py ),我们可以找出以下内容: p>


  • csrf(request)返回 {'csrf_token' NOTPROVIDED'} 如果 get_token(request)返回None。

  • get_token(request)返回 request.META.get(CSRF_COOKIE,无)



我认为这意味着它将返回如果cookie isn' t成功创建。



修正






对于你,这意味着你应该首先替换

 < 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 /方法=post< input type ='hidden'name ='csrfmiddlewaretoken'value ='randomchars'/>>> 

我们宁愿喜欢

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

之后 - 看看源代码,看看是否可以找到csrf字段。如果你可以看到它,一切都应该在理论上工作。



你还可以检查浏览器中已经设置了csrf cookie,例如在Chrome中,右键单击网页,然后选择 Insepect Element 。选择资源标签,然后点击Cookie。您应该找到一个cookie名称 csrftoken



如果仍然有问题,请仔细检查中间件元组您的 settings.py ,并仔细检查您的浏览器是否像上述那样从您的服务器接受cookier。


i am trying to do a login in django but i get this error, i check the CSRF documentation and nothing works for me.

Here is the 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>

Like you see above i use the {% csrf_token %} and i have 'django.middleware.csrf.CsrfViewMiddleware' in my installed apps.

And my views are:

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

i redirect to an other HTML file where i dont use the {% csrf_token %}.

解决方案

Theory


A couple of things are required to make the csrf protection work (check out the docs):

  1. Your browser has to accept cookies from your server
  2. Make sure you have 'django.middleware.csrf.CsrfViewMiddleware' included as middleware in your settings.py (alternatively use the decorator csrf_protect() on particular views you want to protect)
  3. Make sure you pass on the csrf token from django.core.context_processors.csrf to the context manager.

When you load your page, have a look in the page source using your favorite browser. Don't open the template html file, open the url which point to the view containing the form. Look at where you placed the {% csrf_token %}. If you see something like

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

you should be ok.

If you on the other hand see NOTPROVIDED, something has gone wrong while creating the csrf token. By looking in the source code (context_processors.py and csrf.py), we can find out what:

  • csrf(request) returns {'csrf_token': 'NOTPROVIDED'} if get_token(request) returns None.
  • get_token(request) returns request.META.get("CSRF_COOKIE", None).

I assume this means that it would return None if the cookie isn't successfully created.

Fix


For you, this means that you should first replace

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

with

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

We'd like the csrf field to be inside <form>...</form>, not inside <form>. As the code is at the moment, it will be converted to

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

and we would rather like

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

After that - have a look at the source code, and see if you can find the csrf field. If you can see it, everything should work in theory.

You can also check that the csrf cookie has been set in your browser, e.g. in Chrome, right-click the web page, and select Insepect Element. Select the Resources tab, and click on cookies. You should find a cookie name csrftoken there.

If you still have problems, double-check the middleware tuple in your settings.py and double-check that your browser accept cookier from your server as described above.

这篇关于禁止(403)CSRF验证失败。请求中止。即使使用{%csrf_token%}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆