31. Django 2.1.7 模板 - CSRF 跨站请求伪造
时间:2026-01-07
31. Django 2.1.7 模板 - CSRF 跨站请求伪造
CSRF

CSRF(跨站请求伪造)全拼为Cross-Site Request Forgery,翻译为跨站请求伪造。攻击者通过盗用你的身份,以你的名义发送恶意请求,可以进行诸如发邮件、发消息、盗取账号、购买商品和虚拟货币转账等操作,严重威胁个人隐私和财产安全。
CSRF示意图如下:

防止CSRF需要优先采用POST方式传输敏感数据,并详细介绍如何防范POST请求中的 CSRF 攻击方法及在 Django 中的应用实例。
下面开启两个Django服务,来模拟一下攻击过程。首先来构建第一个Django项目
- 打开assetinfo/views.py文件,创建视图login,login_check, post和post_action。代码语言:javascript代码运行次数:0
运行
复制
点击登录按钮后,将用户名和密码提交到服务器,并根据校验判断是否成功。若成功,则在session中存储用户名并在主页显示;否则返回登录页面。
- 打开assetinfo/urls.py文件,配置url。代码语言:javascript代码运行次数:0
运行
复制
urlpatterns = [ # ex:/assetinfo/login path('login/', views.login), # ex:/assetinfo/login_check path('login_check/', views.login_check), # ex:/assetinfo/post path('post/', views.post), # ex:/assetinfo/post_action path('post_action/', views.post_action),]登录后复制
- 在templates/assetinfo/目录下创建login.html和post.html。
login.html代码语言:javascript代码运行次数:0
运行
复制
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>用户登录</title></head><body><form method="post" action="/assetinfo/login_check/"> 用户名:<input type="text" name="username"/><br/> 密码:<input type="password" name="password"/><br/> <input type="submit" value="提交"/></form></body></html>登录后复制
post.html代码语言:javascript代码运行次数:0
运行
复制
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>发帖页面</title></head><body><form method="post" action="/assetinfo/post_action/"> 标题:<input type="text" name="title"/><br/> 内容:<textarea name="content"></textarea> <input type="submit" value="发帖"/></form></body></html>登录后复制
- 启动运行服务器。代码语言:javascript代码运行次数:0
运行
复制
python3 manage.py runserver登录后复制
- 在浏览器中输入如下网址,将这个标签称为网站A。
http://127.0.0.1:8000/assetinfo/login/
浏览效果如下图:

输入账号、密码,登录之后,进入发帖页面,如下:

在Django中创建第二个项目并模拟另一个网站,首先需要复制`templates/assetinfo/post.html`的内容到新项目的相应文件夹,然后进行必要的路径更改。此过程不涉及任何JavaScript代码的运行次数。
运行
复制
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>B网站模拟请求页面</title></head><body><form method="post" action="http://127.0.0.1:8000/assetinfo/post_action/"> 标题:<input type="text" name="title"/><br/> 内容:<textarea name="content"></textarea> <input type="submit" value="发帖"/></form></body></html>登录后复制
- 在windows中浏览器查看效果如下图,将这个标签称为网站B。

在Django项目中移除CSRF保护 打开settings.py文件。 禁用CSRF中间件,将`'django.middleware.csrf.CsrfViewMiddleware'`行注释或删除。

- 点击浏览器的第一个标签即网站A,点击"发帖"按钮后如下图:

- 点击浏览器的第二个标签即网站B,点击“发帖”按钮后如下图:

通过action直接访问网站A的地址,成功执行发帖。
对比两步骤,无论是网站A还是B均可访问网站A的post_action视图,此为安全隐患;防范CSRF至关重要。
- Django提供了csrf中间件用于防止CSRF攻击,只需要在网站A的mysite/settings.py中启用csrf中间件即可。

在开始 Django 时,请确保将中间件添加到 MIDDLEWARE 中的生产配置。例如:```python # 导入所需模块 from django.conf import settings from django.core.exceptions import ImproperlyConfigured class Middleware(object): def __init__(self, get_response=None): self.get_response = get_response def __call__(self, request): response = self.process_request(request) return response def process_request(self, request): # 这里处理请求逻辑... raise NotImplementedError(This should never happen) middleware_classes = getattr(settings, MIDDLEWARE, []) if not isinstance(middleware_classes, list): raise ImproperlyConfigured(The MIDDLEWARE setting must be a list.) for middleware in middleware_classes: try: middleware(request) except Exception as e: logging.error(fError occurred while processing request: {e}) return response ```
运行
复制
MIDDLEWARE = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',)登录后复制
- 回到windows浏览器中,分别在网站A、网站B中点击“提交”按钮,效果一样,如下图:

遇到问题啦!因为模板文件无法被网站A访问了,并且还在使用标签csrf_token进行保护。需要检查一下是否引入了正确的脚本或者配置错误。修复后,可以继续正常使用功能。
运行
复制
{% csrf_token %}登录后复制

- 回到windows浏览器中,在网站A中点击“提交”按钮,效果如下图:

- 回到windows浏览器中,在网站B中点击“提交”按钮,效果如下图:

好的,我在Django项目中已成功实现了CSRF的防护机制。总结了关键点:我将重要数据如金额和积分进行汇总,并通过POST方式进行传输。为此,我激活了CSRF中间件,默认在表单以标记形式()的形式提供防护原理。这样可以有效防止XSS攻击等常见安全威胁。
加入标签后,可以查看post.html的源代码,发现多了一个隐藏域。

在浏览器的“开发者工具”中查看cookie信息。

中间件标签和CSRF保护当启用中间件并加入标签`csrf_token`后,会向客户端浏览器写入一条Cookie信息,该信息的值与隐藏域`input`元素的`value`属性一致。提交时,这条信息首先由`csrf`中间件验证。如果对比失败,则返回面,而不会进行后续处理。
以上就是31. Django 2.1.7 模板 - CSRF 跨站请求伪造的详细内容,更多请关注其它相关文章!
