一:目录

  1)简介及无CSRF时存在隐患

  2)csrf原理

  3)csrf 设置

  4)Form提交(CSRF)

  5)Ajax提交(CSRF)
    CSRF请求头 X-CSRFToken

二:csrf简介 

  csrf主要是为了防止跨站请求伪造(XSS攻击别人可以提交运行JS代码)

  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

二:csrf原理

      客户端发请求,如果是第一次过来,比如GET,我不仅把数据数据你,还给一串加密串,只我自己能反解。

   你下一次过来提交数据的时候,你要带这串来,这样我才允许,不然允许提交数据。

   这个一般体现在那里?如果你往后台发POST请求,你把CSRF禁掉话,会报403名错误了。

    django做了一层防护,GET不会有影响,POST的时候会在来你发过来的请求你找那个随机字符串。

    但是我们没有这个字符串。所以禁止。

    我们可以在页面form请求加一
        {{csrf_token}}生成随机串 这个就是CSRF的token.这样显示是没有用的。

  在form里{%csrf_token%}后台才能拿到token 这是django csft原理

 比如:别人的网站写JS代码,但是提交了我们的网站,如果没有开启csrf他就直接提交过来了,并运行了代码,这是很危险的。

  如果开吂CSRF。别人的网站没有随机token.他就不能提交代码到我们的网站。

三:csrf设置  

    settings:
'django.middleware.csrf.CsrfViewMiddleware', form表单 <form action="/login/" method="post">
{% csrf_token %} <!--post提供token给后台-->
<input type="text" name="username">
<input type="text" name="password">
<input type="checkbox" value="" name="rmb">免登录10秒
<input type="submit" name="+">
</form>

  # {% csrf_token %}不仅在页面中生成,在cookie中也有生成.如图所示

  

  

四:form提交数据

  上面的提交需要csft_token传入到后台。我们有两种方式提交。第一种:普通submit,;第二种ajax提交。ajax也要带token,这能提交数据到后台

  普通submit提交,只需要在form里设置

 {% csrf_token %}

  提交POST后页面和cookie效果,会生成token:

   <form action="/login/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='GGO5hq95CfY3PrbGU2wep1WOpbMZOYNJ02QunbqKQOmeh1ShXNC1IIiTbut1Yij2' />
<input type="text" name="username">
<input type="text" name="password">
<input type="checkbox" value="" name="rmb">免登录10秒
<input type="submit" name="+">
</form>
</body>
</html>

  浏览器cookie
Request Cookies 212
Hm_lpvt_407473d433e871de861cf818aa1405a1 1510386206 N/A N/A N/A 53
Hm_lvt_407473d433e871de861cf818aa1405a1 1509847957,1509936833,1509966824,1510386206 N/A N/A N/A 85
csrftoken 4MGKIn5K2p8K3hYkPKPagY0akHpjieqZo8I9O8mpgYwVvRFVSvVXzFmf606lsyWi
N/A N/A N/A 74
Response Cookies 139
csrftoken 4MGKIn5K2p8K3hYkPKPagY0akHpjieqZo8I9O8mpgYwVvRFVSvVXzFmf606lsyWi
/ 364.0 days 139

五:ajax提交  

AJAX只要把csrftoken拿过来,放在请求头发过去就行了
django里token的KEY是什么:X-CSRFtoke
   from django.conf import settings

    print(settings.CSRF_HEADER_NAME)===>HTTP_X_CSRFTOKEN(jdango会在前面加HTTP_)==>X-CSRFtoken(请求头不能加下划线)

    按django规范来写就是X-CSRFtoken

  ajax提交两种方法:

  1)在ajax里提交headers:{"X-CSRFtoken":csrftoken},但是如果提交ajax非常多的时候就不方便,可以设置全局提交。

  

<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$("#btn").click(
function(){
//获取token
var csrftoken=$.cookie("csrftoken") $.ajax({
url:"/login/",
type:"POST",
//token放在请求头
headers:{"X-CSRFtoken":csrftoken},
data:{"username":"root","password":123},
success:function(data){ } })
})
</script>
  2)全文提交
    #方式2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="/login/" method="post">
{% csrf_token %}
<input type="text" name="username">
<input type="text" name="password">
<input type="checkbox" value="" name="rmb">免登录10秒
<input type="submit" name="+">
<input id="btn" type="button" value="增加">
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$("#btn").click(
function(){
//这就是发ajax请求
{# obj=XMLHttpRequest()#}
{# obj.open()#}
{# obj.send()#}
//可以对整个页面所有的ajax请求做配置
//方式2
$.ajaxSetup({
//表示在发送ajax请求之前执行,这是全局中配置,比如下面有好多个ajax 请求
beforeSend:function(xhr,settings){
//xhr表示XML HTTP requst对象,所有AJAZ操作
xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken"))
}
})
//获取token
{# var csrftoken=$.cookie("csrftoken")#} $.ajax({
url:"/login/",
type:"POST",
//token放在请求头
//方式1
{# headers:{"X-CSRFtoken":$.cookie("csrftoken")#}
data:{"username":"root","password":123},
success:function(data){ } })
})
</script>
</body>
</html>

  3)其他问题

  A)

    #现在是全局都加了token,如果有几个就不需要token验证,如何处理? 给不需要验证的请求加@csrf_exempt装饰器
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

  B)GET是不需要提交token认证的,所以修改如下

#上面POST和GET都是token验证,其实GET是不需要token的,如何处理?
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
{% csrf_token %} <input type="button" onclick="Do();" value="Do it"/> <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
<script src="/static/plugin/jquery/jquery.cookie.js"></script>
<script type="text/javascript">
var csrftoken = $.cookie('csrftoken'); function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/
.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
function Do(){ $.ajax({
url:"/app01/test/",
data:{id:1},
type:'POST',
success:function(data){
console.log(data);
}
}); }
</script>
</body>
</html>

  总结:

  1)csrf主要是在settings里面设置,这个设置是全局的,特别设置可以使用@csrf_protect装饰器,即使全局中没有开启csrf验证,也要求验证。@csrf_exempt装饰器,可以要求不需要验证

  2)在页面form设置{% csrf_token %}

  3) 普通提交,后台不需要做任务修改

  4)ajax提交,需要把token发送到后台,后台也不需要做任务修改

21)django-csrf(跨站请求伪造)的更多相关文章

  1. Python菜鸟之路:Django CSRF跨站请求伪造

    前言 CSRF,Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对 ...

  2. ajax向Django前后端提交请求和CSRF跨站请求伪造

    1.ajax登录示例 urls.py from django.conf.urls import url from django.contrib import admin from app01 impo ...

  3. python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)

    一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...

  4. 第三百一十五节,Django框架,CSRF跨站请求伪造

    第三百一十五节,Django框架,CSRF跨站请求伪造  全局CSRF 如果要启用防止CSRF跨站请求伪造,就需要在中间件开启CSRF #中间件 MIDDLEWARE = [ 'django.midd ...

  5. Django中的CSRF(跨站请求伪造)

    Django中的CSRF(跨站请求伪造) Django CSRF  什么是CSFR 即跨站请求伪装,就是通常所说的钓鱼网站. 钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别? (页面是怎么来的? ...

  6. Django框架 之 基于Ajax中csrf跨站请求伪造

    Django框架 之 基于Ajax中csrf跨站请求伪造 ajax中csrf跨站请求伪造 方式一 1 2 3 $.ajaxSetup({     data: {csrfmiddlewaretoken: ...

  7. 十三 Django框架,CSRF跨站请求伪造

     全局CSRF 如果要启用防止CSRF跨站请求伪造,就需要在中间件开启CSRF #中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMidd ...

  8. Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)

    摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...

  9. django上课笔记3-ORM补充-CSRF (跨站请求伪造)

    一.ORM补充 ORM操作三大难点: 正向操作反向操作连表 其它基本操作(包含F Q extra) 性能相关的操作 class UserInfo(models.Model): uid = models ...

  10. Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)

    Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造)   摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...

随机推荐

  1. springboot(十八):解决跨域问题

    在controller上添加@CrossOrigin注解,如下: @RestController @RequestMapping("course") @CrossOrigin pu ...

  2. 4.mysql(slow_log/generic_log/audit)

    一.慢查询日志进阶 <1>相关参数 1.slow_query_log #是否开启慢查询日志 2.slow_query_log_file #慢查询日志文件名,在my.cnf我们已经定义为sl ...

  3. 设计前沿:16款扁平风格 iOS 7 图标设计

    最新发布的 iOS 7 抛弃了曾经倍受追捧的拟物化设计,采用扁平化,极简设计的界面.对于 iOS 平台来说,采用没有阴影的平面设计其实是有道理的.以前的屏幕分辨率有限,必要的阴影可以填补小尺寸,分辨率 ...

  4. 七、文件IO——I/O处理方式和文件锁

    7.1 I/O 处理方式 7.1.1 I/O处理的五种模型 阻塞I/O模型 若所调用的 I/O 函数没有完成相关的功能就会使进程挂起,直到相关数据到达才会返回.如 终端.网络设备的访问. 非阻塞模型 ...

  5. Debian Security Advisory(Debian安全报告) DSA-4406-1 waagent

    Package        : waagentCVE ID         : CVE-2019-0804 Francis McBratney发现Windows Azure Linux代理创建了具有 ...

  6. luogu P3767 膜法

    传送门 这题如果没有删除操作,可以直接使用可持久化并查集 注意到这种可持久化的依赖关系(是这样说的把)是一棵树,然后对于一个点,自己的操作会影响自己的那棵子树,并且如果是删除操作,就会使得一个子树没有 ...

  7. python2 编码与解码

    #!coding: utf-8 s = "特斯拉" s_to_unicode = s.decode("utf-8") unicode_to_gbk = s_to ...

  8. 谈谈jQuery中的数据类型检测

    这次是分享jQuery代码中的一些简写技巧,分析jQuery是如何优化代码的,如何用最少的代码来实现jQuery. 在我们工作中也常常会遇到一些数据类型检测,一些方法调用的形式 1 var arr = ...

  9. UOJ #36「清华集训2014」玛里苟斯

    这怎么想得到啊......... UOJ #36 题意:求随机一个集合的子集的异或和的$k$次方的期望值,保证答案$ \lt 2^{63},1 \leq k \leq 5$ $ Solution:$ ...

  10. List与逗号分隔的字符串相互转换

    如果程序员想实现某种功能,有两条路可以走.一条就是自己实现,一条就是调用别人的实现,别人的实现就是所谓的API.而且大多数情况下,好多“别人”都实现了这个功能.程序员有不得不在这其中选择.大部分情况下 ...