前言
CSRF 是指跨站请求伪造,跨站请求伪造的问题在于,服务器信任来自客户端的数据
如果没有 CSRF 面临的风险是:
跨站请求伪造是指攻击者通过HTTP请求江数据传送到服务器,从而盗取回话的cookie。盗取回话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。
Django中常规使用Csrf
一般是和Form表单结合使用。
在Form 表单中添加 {% csrf_token %}
可以生产一个隐藏的input标签,含有csrf 随机token串,如果不放这个,会403 Forbidden
报错
具体使用详见 【Django中的CSRF使用及ajax请求接口时问题总结】
该链接文章也介绍如何在在Ajax中使用CSRF
Django如何实现的呢?
1、通过全局配置的中间件
django.middleware.csrf.CsrfViewMiddleware
2、可以局部在某个view视图上设置
from django.views.decorators.csrf import csrf_protect
@csrf_project
def index(request):
pass
注意: 这个装饰器和中间件不冲突,如果注释中间件,它也是生效的
Django中如何禁用CSRF
1、注释掉settings.py中MIDDLEWARE中配置的
MIDDLEWARE = [
# django.middleware.csrf.CsrfViewMiddleware
]
当然这里注释是全局性的,但是局部的想要开启,可以通过上面的 csrf_project
装饰器实现
2、csrf_project 局部开启,对应的是 csrf_exempt 局部禁用
from django.views.decorators.csrf import csrf_protect, csrf_exempt
@csrf_exempt
def index(request):
pass
上面是针对函数式视图(FBV
)添加,类视图(CBV
)有所不同
Django 类视图禁用CSRF
在类视图上禁用CSRF ,核心是在dispatch 方法上使用 csrf_exempt, 可以直接使用,也可以使用 method_decorator 装饰器作用在类上实现
Demo演示为
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect, csrf_exempt
class IndexView(View):
@csrf_exempt
def dispatch(self, request):
pass
def get(self, reqeust):
pass
def post(self, reqeust):
pass
除了在类的方法上添加之外,也可以直接在类上添加,然后通过 method_decorator
的name
属性执行方法名
@method_decorator(csrf_exempt, name='dispatch')
class IndexView(View):
@csrf_exempt
通过中间件白名单实现禁用
我们知道中间件是在Django的request和response过程中对请求进行梳理的
所以这里撰写一个中间件,如果对应的白名单
中存在URL,则对其进行CSRF的禁用
# blog/middleware.py
import re
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
class BlogIgnoreCsrfMiddleware(MiddlewareMixin):
def process_request(self, request, *args, **kwargs):
if hasattr(settings, 'URL_IGNORE_CSRF_LIST'):
url_ignore_list = settings.URL_IGNORE_CSRF_LIST
else:
url_ignore_list = []
for u in url_ignore_list:
if re.match(u, request.path):
print(request.path, u)
request.csrf_processing_done = True
然后再 settings.py 中配置
MIDDLEWARE = [
# 放到第一个位置
'blog.middleware.BlogIgnoreCsrfMiddleware',
... ...
]
URL_IGNORE_CSRF_LIST = [r'^/blog/post/[0-9]{1,5}/like/',]
然后请求博客的点赞喜欢功能,发现是可以的
But: 不建议禁用CSRF 哦~
如果是Form表单提交,一定要加 {% csrf_token %}
如果是ajax 提交,就可以参考 【Django中的CSRF使用及ajax请求接口时问题总结】 来实现