一、CSRF验证
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF。是一种对网站的恶意利用。
Django通过在post请求中添加csrfmiddlewaretoken参数进行验证,防止CSRF攻击。
添加csrfmiddlewaretoken参数的几种方式:
1. 在一般的form表单中使用{% csrf_token %}标签
<!DOCTYPE html><html><body>
<form action="/user/login/" method="post">
{% csrf_token %}
</form>
</body></html>
django的模板会自动把{% csrf_token %} 渲染成<input>标签:
<!DOCTYPE html><html><body>
<form action="/user/login/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="***********">
</form>
</body></html>
2. 在一般的form表单中使用{{ csrf_token }}标签
<!DOCTYPE html><html><body>
<form action="/user/login/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
</form>
</body></html>
得到的结果是一样的
<!DOCTYPE html><html><body>
<form action="/user/login/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="***********">
</form>
</body></html>
3. 在ajax的post提交中
在基本模板中添加,所有ajax提交的post数据中都会自动带上csrfmiddlewaretoken参数。
<script type="text/javascript">$.ajaxSetup({data: {csrfmiddlewaretoken: '{{ csrf_token }}' }});</script>
4. 在视图函数中返回csrf_token的值
from django.http import JsonResponse
from django.middleware.csrf import get_token
def get_csrf_token(request):
return JsonResponse({'csrf_token': get_token(request) or 'NOTPROVIDED'})
二、访问异常
1. 403异常
Django的django.middleware.csrf.CsrfViewMiddleware中间件会在每次收到POST请求时进行以下操作:
a. 通过一定的规则校验请求的Referer是否正常
b. 若Referer是正常的,校验Referer的主机名是否包含在CSRF_TRUSTED_ORIGINS中
c. 若前面的校验通过,用加密算法校验cookie中的csrftoken值和POST的csrfmiddlewaretoken值的关系
d. 若上面的任意一步校验失败则返回403异常
因此启用该中间件后POST请求需要满足以下条件,否则会返回403异常:
a. 请求头中包含正确的Referer值
b. settings文件中配置了正确的CSRF_TRUSTED_ORIGINS值
c. POST请求发送的数据中包含正确的csrfmiddlewaretoken值
d. 请求头的cookie中包含正确的csrftoken值
2. 400异常
Django关闭调试模式后,需要把允许访问的IP地址加入到settings的ALLOWED_HOSTS中,否则不在ALLOWED_HOSTS列表中的IP地址访问网站会得到400异常。