什么是CSRF?

CSRF原理图
攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作。例如:
一个网站用户Bob可能正在浏览聊天论坛,而同时另一个用户Alice也在此论坛中,并且后者刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片src。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。CSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。

csrf_token 的全局强制认证

若想要使用csrf_token
首先去settings里面把csrf中间件的启用打开

1
2
3
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]

前端代码 (FORM表单)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<!-- form表单下的认证实现 -->
<form action="/login/" method="post">
{# 这个是接收令牌的位置 #}
{% csrf_token %}
<input type="text" name="account">
<input type="submit">
</form>

<!-- ajax下的认证实现-->
<script>
csrftoken = $('input[name="csrfmiddlewaretoken"]').val()
$.ajax({
type:"POST",
url : '/xxxx/',
data: {"name":'xxxx'},
headers : {'X-CSRFToken': token},
success: function(){
console.log(data)
}
})
</script>
</body>
</html>

后端代码

1
2
3
4
5
6
7
8
9
10
11
# 登陆用到的验证装饰器(FBV)
@csrf_protect
def login(request):
if request.method == 'GET':
return render(request, "login.html")

else:
account = request.POST.get('account')
print(account)

return HttpResponse('ok')

关闭全局csrf中间件后csrf-token的灵活使用

csrf_token(白名单exempt)(黑名单protect)

导包语句

1
from django.views.decorators.csrf import csrf_exempt,csrf_protect

csrf_exempt , csrf_protect 两个都是装饰器
protect 必须使用CBV应用装饰器 必须使用 method_decorator,把装饰器当作参数传进去。

1
2
from django.views import View
from django.utils.decorators import method_decorator

csrf_exempt白名单 (CBV)

1
2
3
4
5
6
7
8
9
# Login被添加进了白名单
@method_decorator(csrf_exempt)
class Login(View):

def get(self):
pass

def post(self):
pass

csrf_protect白名单 (CBV)

1
2
3
4
5
6
7
8
9
# Login被添加进了黑名单        
@method_decorator(csrf_protect, name='get')
class Login(View):

def get(self):
pass

def post(self):
pass