学习笔记,仅供参考,有错必纠



文章目录





中间件Middleware



跨站请求伪造



  • 跨站请求伪造攻击

某些恶意网站上包含链接、表单按钮或者JavaScript,它们会利用登录过的用户在浏览器中的认证信息,试图在我们的网站上完成某些操作,这就是跨站请求伪造



  • CSRF
Cross-Site Request Forgey
跨 站点 请求 伪装

CSRF中间件模板标签提供了对跨站请求伪造的简单防护,它可以防止其它表单提交到我们的Django 服务器中。



防护方案



  • 取消 csrf 验证(不推荐)

删除(注释)settings.py文件中的MIDDLEWARE列表里的 ​​django.middleware.csrf.CsrfViewMiddleware​​ 的中间件。



  • 开放验证

在视图处理函数增加​​@csrf_protect​​装饰器

@csrf_protect
def post_views(request):
pass



  • 通过验证(最常用)

在我们的表单中添加一个标签

{% csrf_token %}



举个例子



我们先打开settings.py,并打开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',
# 'mymiddleware.checklogin.MyMiddleWare',
# 'mymiddleware.checklogin.VisitLimit',
]



我们向登录界面http://127.0.0.1:8000/userinfo/login/发起请求,并进行登录操作,点击​​登录​​后,网页产生了403错误(没有请求权限):

Django(part42)--跨站请求伪造_django

它提示我们​​CSRF token​​丢失或不正确。



现在,为了能够成功提交数据,我们需要在提交表单的模板中增加一个标识符:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="/userinfo/login/" method="POST">
{% csrf_token %}
<div>
<lable>用户名</lable>
<input type="text" name="username"
value="{{ username }}">
</div>
<div>
<lable>密码</lable>
<input type="password" name="password">
</div>
<div>
<lable for="id_remember">记住密码</lable>
<input type="checkbox" name="remember" id="id_remember"
value="1">
</div>
<div>
<input type="submit" value="登陆">
</div>

</form>

</body>
</html>

现在,我们再次对登录界面http://127.0.0.1:8000/userinfo/login/发起请求,并进行登录:

Django(part42)--跨站请求伪造_django_02

可以看到,我们正常登录了。

我们查看一下登录界面的网页源代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="/userinfo/login/" method="POST">
<input type="hidden" name="csrfmiddlewaretoken" value="7azE5TZgsdRF6BqkN9jlfBZgtJOx0fvQhdBZETEEo2DATMStYJoY6GY8vWSQi9Pp">
<div>
<lable>用户名</lable>
<input type="text" name="username"
value="">
</div>
<div>
<lable>密码</lable>
<input type="password" name="password">
</div>
<div>
<lable for="id_remember">记住密码</lable>
<input type="checkbox" name="remember" id="id_remember"
value="1">
</div>
<div>
<input type="submit" value="登陆">
</div>

</form>

</body>
</html>

我们发现​​CSRF token​​标签自动生成了一个input标记:

<input type="hidden" name="csrfmiddlewaretoken" value="7azE5TZgsdRF6BqkN9jlfBZgtJOx0fvQhdBZETEEo2DATMStYJoY6GY8vWSQi9Pp">

value参数后的字符串是Django服务器提供给我们的密钥。如果提交的表单中没有带这串密钥,或者提供的密钥和Django给我们的不一致,则不会提交成功,这就起到了防护作用,防止其他网站恶意提交给我们数据。



  • 友情提示

当我们在settings.py中设置了CSRF中间件,并在form表单中增加了​​CSRF token​​标签。那么,如果不是我们服务器发布的表单,而是其他网站发布的表单向我们提交数据,那么将不会提交成功。