发布网友 发布时间:2024-09-29 04:39
共1个回答
热心网友 时间:2024-10-03 05:10
导读:今天首席CTO笔记来给各位分享关于django怎么验证csrf的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
求助django实现前端页面检索功能的代码设我们的django博客应用有如下的文章模型:
blog/models.pyclassPost(models.Model):
#标题
title=models.CharField(max_length=70)
#正文
body=models.TextField()
#其他属性
def__str__(self):
returnself.title
先看到第1步,用户在搜索框输入搜索关键词,因此我们要在博客上为用户提供一个搜索表单,html表单代码大概像这样:
formmethod="get"action="/search/"
{%csrf_token%}inputtype="search"placeholder="搜索"required
buttontype="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.pydefsearch(request):
q=request.GET.get('q')
error_msg=''
ifnotq:
error_msg='请输入关键词'
returnrender(request,'blog/errors.html',{'error_msg':error_msg})
post_list=Post.objects.filter(title__icontains=q)
returnrender(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是查询表达式(Fieldlookups),其用法是在模型需要筛选的属性后面跟上两个下划线。django内置了很多查询表达式,建议过一遍django官方留个印象,了解每个表达式的作用,以后碰到相关的需求就可以快速定位到文档查询其用途:Fieldlookups
接下来就是渲染搜索结果页面,显示符合搜索条件的文章列表,下面是一个模板的简单示例:
results.html
{%iferror_msg%}p{{error_msg}}/p{%endif%}
{%forpostinpost_list%}div
在这里显示文章的相应信息/div{%empty%}divclass="no-post"
没有搜索到符合条件的文章/div{%endfor%}
有了视图函数后记得把视图函数映射到相应了URL,前面我们表单数据提交的URL为/search/,因此将视图函数search绑定到该URL上。
blog/urls.pyurlpatterns=[
#其他url配置
url(r'^search/$',views.search,name='search'),]
大功告成!
如何验证csrf漏洞
CSRF(CrossSiteRequestForgey)是排在OWASPTop10第5位的漏洞,它迫使已被认证的用户在Web系统上执行其所不欲的操作。这种攻击依赖于以下:
1)Web浏览器对会话相关信息的处理方式(如cookie或Http认证信息)
2)攻击者对正确的Web系统的URL的了解;
3)应用会话管理仅依赖于浏览器所了解的信息;
4)一些HTML的tag会导致对http(s)资源的直接访问其中,前3点是确认系统是否存在该漏洞的主要前提,第4点则是用来帮助攻击者利用该漏洞的。
第1点:浏览器自动发送用于识别用户会话的信息,假设site是一个Web应用站点,victim是一个已经在该系统上经过认证的用户。在server的响应中,site发送一个带有代表victim身份的cookie给victim,原则上,一旦浏览器接收到了服务器发送的cookie,就会在后面对站点的访问中都带上这个cookie;
第2点:如果应用在URL中没有使用会话相关的信息,那就意味着应用的URL,它们的参数,相应的值可以被识别。
第3点:是指诸如cookie、或者是基于http的认证信息,存放在浏览器中后,就会包含在后面的每次请求中。
下面,我们用Get方法在做个例子,如果用户已经通过了认证,那么在他做下一次请求时,请求数据中会自动加上cookie
GET请求一般会有多种原因产生,
*用户真正在访问Web系统;
*用户在访问地址栏中切实敲入了URL;
*用户点击了一个连接指向了这个URL;
这些调用对于系统来说是无法区别的,特别的,第三种方式相对来说是极为危险的,有很多种方法可以用来仿造连接的真实属性,连接可以被嵌入到一封邮件中,或者在某个恶意网站上,看上去这个连接好像是在访问另一个网站,而事实上却是被引到了Web系统的访问上。如果用户点击了连接,由于它已经被系统认证通过了,浏览器就会对系统提交一个待用认证信息的GET请求。这就在系统上完成了一个操作(尽管这个操作不是用户本身所期望做的)。
页面刷新时怎么进行csrftoken判断我上次在用django的时候遇到过这个问题,资料如下:django对POST请求需要csrf_token验证,后端会检测前端发过来的token,如果有问题可以会出现403Forbidden的错误。这个token是由后端在页面GET请求页面文件的时候就放进去的,可以在模板中使用
怎么解决django的防csrf?djangopost出现403的解决办法据说,从django1.x开始,加入了CSRF保护。
CSRF(Cross-siterequestforgery跨站请求伪造,也被称成为“oneclickattack”或者sessionriding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。-------来自百度百科
报错:Forbidden(403)
CSRFverificationfailed.Requestaborted.Help
Reasongivenforfailure:CSRFtokenmissingorincorrect.
Ingeneral,thiscanoccurwhenthereisagenuineCrossSiteRequestForgery,orwhenDjango'sCSRFmechanismhasnotbeenusedcorrectly.ForPOSTforms,youneedtoensure:
Yourbrowserisacceptingcookies.
TheviewfunctionusesRequestContextforthetemplate,insteadofContext.
Inthetemplate,thereisa{%csrf_token%}templatetaginsideeachPOSTformthattargetsaninternalURL.
IfyouarenotusingCsrfViewMiddleware,thenyoumustusecsrf_protectonanyviewsthatusethecsrf_tokentemplatetag,aswellasthosethatacceptthePOSTdata.
You'reseeingthehelpsectionofthispagebecauseyouhaveDEBUG=TrueinyourDjangosettingsfile.ChangethattoFalse,andonlytheinitialerrormessagewillbedisplayed.
YoucancustomizethispageusingtheCSRF_FAILURE_VIEWsetting.
在网上找解决办法,说是提交参数中要有csrf_token,才能成功。但网上都是1.3或者1.4版本的解决办法,在1.5版本中测试已经不能用了。
在1.5.1版本,我测试可行的解决办法有三种:
一:
关闭csrf保护功能。为视图函数添加@csrf_exempt修饰符。
fromdjango.views.decorators.csrfimportcsrf_exempt@csrf_exemptdefview(request):#yourcode.....当然这样不安全。
二:在模版文件中,每个form提交域中都加上{%csrf_token%}标签,并使用render函数返回视图,或者强行使用RequestContext代替Context。例:fromdjango.shortcutsimportrenderdefcontact(request):form=ContactForm()#这里我使用了一个django的表格returnrender(request,'contact.html',{'form':form})
或者:
fromdjango.shortcutsimportrender_to_responsedefcontact(request):form=ContactForm()#这里我使用了一个django的表格returnrender_to_response('contact.html',{'form':form},context_instance=RequestContext(request))
contact.html的内容:
htmlheadstyletype="text/css"ul.errorlist{margin:0;padding:0;}.errorlistli{background-color:red;color:white;display:block;font-size:10px;margin:003px;padding:4px5px;}/styletitlesend/title/headbodyh1Contactus/h1formaction=""method="post"{%csrf_token%}divclass="field"{{form.subject.errors}}labelfor="id_subject"工作:/label{{form.subject}}/divdivclass="field"{{form.email.errors}}labelfor="id_email"你的邮箱地址:/label{{form.email}}/divdivclass="field"{{form.message.errors}}labelfor="id_message"消息:/label{{form.message}}/divinputtype="submit"value="Submit"/form/body/html
三:
方法二显然只能*在django模版中使用,那如果我们使用javascript或者AJAX的时候呢?怎么添加csrf_token呢?
我们可以使用javascript来提取cookies中的csrf_token。
functiongetCookie(name){varcookieValue=null;if(document.cookiedocument.cookie!=''){varcookies=document.cookie.split(';');for(vari=0;icookies.length;i++){varcookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+'=')){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break;}}}returncookieValue;}
或者这个好理解的:
functiongetCookie(sName){varaCookie=document.cookie.split(";");for(vari=0;iaCookie.length;i++){varaCrumb=aCookie[i].split("=");if(sName==aCrumb[0])return(aCrumb[1]);}returnnull;}
AJAX中这样用:$.post(url,{"csrfmiddlewaretoken":getCookie('csrftoken')},function(data){alert(data);});
但是有一个问题,当有一个新用户访问这个页面的时候,cookie里并没有csrftoken这个值。只有进行第二种方法,才能在cookie里生成csrftoken值。解决此问题的方法随后更新。
完全可以满足简单的建站需要。
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中,为每个POSTform增加一个{%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攻击,返回403Forbidden.
在通过ajax发送POST请求到服务器时,要求增加一个x-csrftokenheader,其值为cookie里的csrftoken的值,服务湍收到后,django会验证这个请求的cookie里的csrftoken字段与ajaxpost消息头中的x-csrftokenheader是否相同,如果相同,则表明是一个合法的请求
具体实现方法
django为用户实现防止跨站请求伪造的功能,通过中间件django.middleware.csrf.CsrfViewMiddleware来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:fromdjango.views.decorators.csrfimportcsrf_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:CSRFFailed:CSRFtokenmissingorincorrect解决方案:
当我用django的超级用户登录时候,出现CSRF的错误,如图,怎么解决啊??需要在form后面加上csrf_token。如:
formmethod="post"{%csrf_token%}
xxx
/form
或者修改django源码:django/middleware/csrf.pyprocess_view
在“#Iftheuserdoesn'thaveaCSRFcookie”上面增加以下代码:
ifrequest.path.startswith('/admin'):
returnaccept()
如果django版本为1.2.5,则修改为:
ifrequest.path.startswith('/admin'):
returnself._accept(request)
这表示请求url是/admin的话,即使form后面没带csrf_token也可以访问。
结语:以上就是首席CTO笔记为大家整理的关于django怎么验证csrf的相关内容解答汇总了,希望对您有所帮助!如果解决了您的问题欢迎分享给更多关注此问题的朋友喔~