栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django-慕课网制作(三)——csrf

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django-慕课网制作(三)——csrf

在慕课网制作(三)我挖了几个坑,今天就是来填坑的,本章主要是介绍什么是csrf。

什么是csrf

首先我们设想一个情境,我们要给某个人转账,张三知道了这个接口是一个post请求,转账就是通过这个点击这个请求。然后张三伪造了一个网站,当我们点击了这个接口,他就自动往张三的账户上进行了转账,因为使我们在本地进行点击,session也是在我们这台电脑上,银行后台就认为是我主动点击的。也退不回来了,那咋办????

有办法,聪明的孩子 (疯狂暗示) 在一下子想到了我可以在 用get请求的网页的时候就在form表单中生成一个随机字符串 在post请求的时候也把这个字符串请求过去,就想到与额外的加了一个锁,虽然说这个方法还有一定的局限性,但是目前的方法就这一个了。

django中实现 from提交

在django的setting.py中他是默认开启了全局的csrf验证,也就是说如果在进行post请求的时候没有带csrf就会报错,我们可以在这里设置csrf验证的开启或关闭

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XframeOptionsMiddleware',
]

上面的这个字段存放的django运行的中间件,现在不在我们探讨的返回

'django.middleware.csrf.CsrfViewMiddleware',

这一个就是用来验证csrf 我们可以把它注释掉,这样就可以让全局都不在验证post

如果我们想要进行csrf给自己网站增加点安全性,我们可以在前段网页的form表单下 加一个 {% csrf_token %} django就自动加了一个隐藏的input 里面存放随机的字符串,在请求的时候 django就自动对着字符串进行判断。

ajex提交数据

下面的 是我转载别人的 关于ajex 看说的挺不错的。

csrf中间件要验证的随机字符串存放在了form表单当中,发送到了后台,那么如果我们使用的是ajax异步请求,是不是也要传送这样一个类似的字符串呢?答案是肯定的,但这个字符串又该来自哪里?其实它来自cookie,在上面的那个小例子当中,我们打开F12元素审查,会发现,在cookie中也存放这样一个csrftoken:

所以下面呢我们就再聊一下ajax请求中如何进行。

首先我们引入两个js文件放在工程项目的static当中,这两个文件是jquery的库文件,方便我们进行请求操作

然后我们把之前的login.html做一个修改:




    
    Title


    
{% csrf_token %} 10s免登录

这个时候我们打开界面,点击按钮,会发现http请求发送403错误,很明显我们直接发送请求是不合适的,并没有带随机字符串过去:

所以,我们应该先从cookie中获取到这个随机字符串,这个随机字符串的名字,我们可以通过之前的验证得出是“csrftoken”:

var csrftoken = $.cookie('csrftoken');

这样变量csrftoken取到的就是我们的随机字符串;但是如果后台想要去接收这个随机字符串,也应该需要一个key,那这个key是什么?我们可以通过查找配置文件,通过控制台输出的方式验证这个key:

from django.conf import settings
print(settings.CSRF_HEADER_NAME)

最后输出的是:

HTTP_X_CSRFTOKEN

但这里需要注意的是,HTTP_X_CSRFTOKEN并不是请求头中发送给django真正拿到的字段名,前端发过去真正的字段名是:

X-CSRFtoken

那为什么从Django的控制台输出会得到HTTP_X_CSRFTOKEN呢?其实我们前端的请求头X-CSRFtoken发送到后台之后,django会做一个名字处理,在原来的字段名前家一个HTTP_,并且将原来的小写字符变成大写的,“-”会处理成下划线“_”,所以会有这两个字段的不一样。但本质上他们指向的都是同一个字符串。知道这一点之后,那么我们前端就可以真正地发起含有CSRF请求头的数据请求了。




    
    Title


    
{% csrf_token %} 10s免登录

在页面中点击按钮之后,会发现请求成功!

那么这个时候有人会问,难道所有的ajax请求,都需要这样获取一次写进去吗,会不会很麻烦。针对这一点,jquery的ajax请求中为我们封装了一个方法:ajaxSetup,它可以为我们所有的ajax请求做一个集体配置,所以我们可以进行如下改造,这样不管你的ajax请求有多少,都可以很方便地进行csrf验证了:




    
    Title


    
{% csrf_token %} 10s免登录
装饰器

在有些时候我们想要在某一个请求下不使用 csrf,有些请求使用,我们可以在对应的 方法上面添加添加一个django自带的装饰器来来进行标识

from django.views.decorators.csrf import csrf_exempt,csrf_protect
 
@csrf_protect
def index(request):
    .....
 
@csrf_exempt
def login(request):
    .....

@csrf_protect 是 开启csrf验证的装饰器,@csrf_exempt是关闭csrf验证的装饰器。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/268572.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号