导读:今天首席CTO笔记来给各位分享关于django如何csrf机制的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
当我用django的超级用户登录时候,出现CSRF的错误,如图,怎么解决啊??
需要在form后面加上csrf_token。如:
form method="post"{% csrf_token %}
xxx
/form
或者修改django源码:django/middleware/csrf.py process_view
在“# If the user doesn't have a CSRF cookie”上面增加以下代码:
if request.path.startswith('/admin'):
return accept()
如果django版本为1.2.5,则修改为:
if request.path.startswith('/admin'):
return self._accept(request)
这表示 请求url是/admin的话,即使form后面没带csrf_token也可以访问。
csrf_token的了解
django中写form表单时csrf_token的作用:
Django下的CSRF预防机制
CSRF预防机制
CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。
token防御的整体思路是:
第一步:后端随机产生一个token,把这个token保存在SESSION状态中;同时,后端把这个token交给前端页面;
第二步:下次前端需要发起请求(比如发帖)的时候把这个token加入到请求数据或者头信息中,一起传给后端;
第三步:后端校验前端请求带过来的token和SESSION里的token是否一致;
1、Django下的CSRF预防机制
django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,
这样就能避免被 CSRF 攻击。
在 templete 中, 为每个 POST form 增加一个 {% csrf_token %} tag. 如下:
在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
在所有的 POST 表单模板中,加一个{% csrf_token %} 标签,它的功能其实是给form增加一个隐藏的input标签,如下
,而这个csrf_token = cookie.csrftoken,在渲染模板时context中有context['csrf_token'] = request.COOKIES['csrftoken']
在通过表单发送POST到服务器时,表单中包含了上面隐藏了crsrmiddlewaretoken这个input项,服务端收到后,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
在通过 ajax 发送POST请求到服务器时,要求增加一个x-csrftoken header,其值为 cookie 里的 csrftoken 的值,服务湍收到后,django会验证这个请求的cookie里的csrftoken字段与ajax post消息头中的x-csrftoken header是否相同,如果相同,则表明是一个合法的请求
具体实现方法
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
1、原理
在客户端页面上添加csrftoken, 服务器端进行验证,服务器端验证的工作通过'django.middleware.csrf.CsrfViewMiddleware'这个中间层来完成。在django当中防御csrf攻击的方式有两种:
1.在表单当中附加csrftoken
2.通过request请求中添加X-CSRFToken请求头。
注意:Django默认对所有的POST请求都进行csrftoken验证,若验证失败则403错误侍候。
Django 设置 cookie 中的 csrftoken
VUE向django发送post返回403:CSRF Failed: CSRF token missing or incorrect解决方案:
如何在Django使用ajax的POST
post方式不同于get方式可以被django直接得到,因为django为post加入了csrf保护, 详细的文档地址
注释:在最新版本中,在setting.py里'django.middleware.csrf.CsrfViewMiddleware',默认是使用中的,如果没有请自行添加,并且确保此引用在其他所有viewware前面
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',//this line is vsrf
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django_cas.middleware.CASMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
如果想避过csrf检测这一层直接使用post的话,有几种方法:
1 需要在views.py里要出发post请求的函数前加入@csrf_exempt ,之前要引入from django.views.decorators.csrf import csrf_exempt
2 在 settings.py 中 MIDDLEWARE_CLASSES 中 注释掉'django.middleware.csrf.CsrfViewMiddleware'
说下正确使用csrf的方法 :
对于ajax.post方法,需要在ajax方法触发前加入一段js,这段我理解是用来生成不同的token,但是很好奇如果禁掉了co
各位是怎么解决django的防csrf
django post出现403的解决办法 据说,从django1.x开始,加入了CSRF保护。
CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。-------来自百度百科
报错:Forbidden (403)
CSRF verification failed. Request aborted.Help
Reason given for failure:CSRF token missing or incorrect.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
在网上找解决办法,说是提交参数中要有csrf_token,才能成功。但网上都是1.3或者1.4版本的解决办法,在1.5版本中测试已经不能用了。
在1.5.1版本,我测试可行的解决办法有三种:
一:
关闭csrf保护功能。为视图函数添加@csrf_exempt修饰符。
from django.views.decorators.csrf import csrf_exempt@csrf_exemptdef view(request): #your code..... 当然这样不安全。
二: 在模版文件中,每个form提交域中都加上{% csrf_token %}标签,并使用render函数返回视图,或者强行使用RequestContext 代替Context。例: from django.shortcuts import renderdef contact(request): form = ContactForm()#这里我使用了一个django的表格 return render(request,'contact.html', {'form': form})
或者:
from django.shortcuts import render_to_responsedef contact(request): form = ContactForm()#这里我使用了一个django的表格 return render_to_response('contact.html', {'form': form}, context_instance=RequestContext(request) )
contact.html的内容:
htmlheadstyle type="text/css" ul.errorlist { margin: 0; padding: 0; } .errorlist li { background-color: red; color: white; display: block; font-size: 10px; margin: 0 0 3px; padding: 4px 5px; }/style titlesend/title/headbody h1Contact us/h1 form action="" method="post" {% csrf_token %} div class="field" {{ form.subject.errors }} label for="id_subject"工作:/label {{ form.subject }} /div div class="field" {{ form.email.errors }} label for="id_email"你的邮箱地址:/label {{ form.email }} /div div class="field" {{ form.message.errors }} label for="id_message"消息:/label {{ form.message }} /div input type="submit" value="Submit" /form/body/html
三:
方法二显然只能限制在django模版中使用,那如果我们使用javascript或者AJAX的时候呢?怎么添加csrf_token呢?
我们可以使用javascript来提取cookies中的csrf_token。
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]); if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }
或者这个好理解的:
function getCookie(sName){ var aCookie=document.cookie.split("; "); for(var i=0;iaCookie.length;i++){ var aCrumb=aCookie[i].split("="); if(sName==aCrumb[0])return (aCrumb[1]); } return null;}
AJAX中这样用: $.post(url, {"csrfmiddlewaretoken":getCookie('csrftoken')}, function (data) {alert(data);});
但是有一个问题,当有一个新用户访问这个页面的时候,cookie里并没有csrftoken这个值。只有进行第二种方法,才能在cookie里生成csrftoken值。解决此问题的方法随后更新。
完全可以满足简单的建站需要。
求助django 实现前端页面检索功能的代码
设我们的 django 博客应用有如下的文章模型:
blog/models.pyclass Post(models.Model):
# 标题
title = models.CharField(max_length=70)
# 正文
body = models.TextField()
# 其他属性
def __str__(self):
return self.title
先看到第 1 步,用户在搜索框输入搜索关键词,因此我们要在博客上为用户提供一个搜索表单,html 表单代码大概像这样:
form method="get" action="/search/"
{% csrf_token %} input type="search" placeholder="搜索" required
button type="submit"搜索/button/form
特别注意在 form 标签下有一个 {% csrf_token %},这是 django 用来防御跨站请求伪造(CSRF)攻击的机制。如果不知道什么是 CSRF 的话也没有关系,只要记住在使用 django 时,前端的表单代码里一定要加上 {% csrf_token %}。
用户输入了搜索关键词并点击了搜索按钮后,数据就被发送给了 django 后台服务器。表单的 action 属性的值为 /search/,表明用户提交的结果将被发送给 /search/ 这个 URL。我们为这个 URL 绑定一个 django 视图函数,在这个视图函数里完成前面第 2 步提到的过程。假设我们把视图函数的代码写在 blog/views.py 里:
blog/views.pydef search(request):
q = request.GET.get('q')
error_msg = ''
if not q:
error_msg = '请输入关键词'
return render(request, 'blog/errors.html', {'error_msg': error_msg})
post_list = Post.objects.filter(title__icontains=q)
return render(request, 'blog/results.html', {'error_msg': error_msg,
'post_list': post_list})
首先我们使用 request.GET.get('q') 获取到用户提交的搜索关键词。用户通过表单提交的数据 django 为我们保存在 request.GET 里,这是一个类似于 Python 字典的对象,所以我们使用 get 方法从字典里取出键 q 对应的值,即用户的搜索关键词。这里字典的键之所以叫 q 是因为我们的表单中搜索框 input 的 name 属性的值是 q,如果修改了 name 属性的值,那么这个键的名称也要相应修改。
接下来我们做了一个小小的校验,如果用户没有输入搜索关键词而提交了表单,我们就无需执行查询,而是渲染一个错误页面提示用户请输入关键词。
如果用户输入了搜索关键词,我们就通过 filter 方法从数据库里过滤出符合条件的所有文章。这里的过滤条件是 title__icontains=q,即 title 中包含(contains)关键字 q,前缀 i 表示不区分大小写。这里 icontains 是查询表达式(Field lookups),其用法是在模型需要筛选的属性后面跟上两个下划线。django 内置了很多查询表达式,建议过一遍 django 官方留个印象,了解每个表达式的作用,以后碰到相关的需求就可以快速定位到文档查询其用途:Field lookups
接下来就是渲染搜索结果页面,显示符合搜索条件的文章列表,下面是一个模板的简单示例:
results.html
{% if error_msg %} p{{ error_msg }}/p{% endif %}
{% for post in post_list %} div
在这里显示文章的相应信息 /div{% empty %} div class="no-post"
没有搜索到符合条件的文章 /div{% endfor %}
有了视图函数后记得把视图函数映射到相应了 URL,前面我们表单数据提交的 URL 为 /search/,因此将视图函数 search 绑定到该 URL 上。
blog/urls.pyurlpatterns = [
# 其他 url 配置
url(r'^search/$', views.search, name='search'),]
大功告成!
结语:以上就是首席CTO笔记为大家整理的关于django如何csrf机制的相关内容解答汇总了,希望对您有所帮助!如果解决了您的问题欢迎分享给更多关注此问题的朋友喔~
以上内容为新媒号(sinv.com.cn)为大家提供!新媒号,坚持更新大家所需的互联网后端知识。希望您喜欢!
版权申明:新媒号所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请发送邮件至 k2#88.com(替换@) 举报,一经查实,本站将立刻删除。