学习记录:requests Django登录测试脚本(解决CSRF、重定向问题)

一、背景

最近在用trae写一个Django学生管理系统,需要验证测试登录功能。

二、脚本验证功能

  • 自动获取CSRF Token

  • 处理登录表单提交

  • 保持登录状态访问其他接口

  • 处理重定向

  • 完整的错误处理

通过正则提取页面的CSRF Token

调用登录接口会重定方向

可以看到接口是会携带CSRF Token去登录的

三、编写思路

1. 为什么使用 Session?

  • HTTP是无状态的 :每次请求都是独立的

  • Session自动管理Cookie :登录成功后,Session会保存服务器返回的Cookie

  • 后续请求自动携带Cookie :访问其他接口时不需要手动处理Cookie

2. CSRF Token 处理

Django的CSRF保护机制需要:

  • 表单中的 csrfmiddlewaretoken :从页面HTML中提取

  • Cookie中的 csrftoken :通过Session自动保存

  • Referer头 :告诉服务器请求来源

3. 登录流程

  1. 获取CSRF Token :访问登录页面,提取隐藏字段

  2. 准备登录数据 :用户名、密码、用户类型、CSRF Token

  3. 发送POST请求 :带上数据和Referer头

  4. 判断登录成功 :通过重定向后的URL判断

  5. 测试其他接口

登录成功后,Session中已有Cookie,直接访问其他需要登录的接口:

  • 首页 ( / )

  • 个人信息页 ( /profile/ )

  • 成绩页 ( /grades/ )

四、验证脚本

复制代码
import requests
import re

session = requests.session()

def get_csrf_token(url):
    response = session.get(url)
    csrf_match = re.search(r'name=["\']csrfmiddlewaretoken["\'][^>]*value=["\']([^"\']+)["\']', response.text)
    if csrf_match:
        return csrf_match.group(1)
    return ''

login_url = 'http://127.0.0.1:8000/login/'
csrf_token = get_csrf_token(login_url)

data = {
    'username': 'admin88',
    'password': 'Aa12345678',
    'user_type': 'teacher',
    'csrfmiddlewaretoken': csrf_token
}

headers = {
    'Referer': 'http://127.0.0.1:8000/login/'
}

res = session.post(url=login_url, data=data, headers=headers, allow_redirects=True)
# print(f"POST状态码: {res.status_code}")
# print(f"重定向后URL: {res.url}")

# 打印响应内容,查看错误信息
# print("\n响应内容:")
# print(res.text)



url = 'http://127.0.0.1:8000/student_list/'
res = session.get(url=url)
print(res.text)

五、遇到的问题及解决方案

问题1:403 Forbidden(CSRF验证失败)

原因 :

  • 没有使用Session获取CSRF Token

  • 没有添加Referer头

解决方案 :

  • 使用 session.get() 获取Token(保存Cookie)

  • 添加 Referer 头指向登录页面

Django 的 CSRF 保护需要验证 三个东西 :

|---------------------|---------|-------------|
| 验证项 | 来源 | 说明 |
| csrfmiddlewaretoken | 表单隐藏字段 | 我们从HTML中提取的 |
| csrftoken | Cookie | Session自动带的 |
| Referer | HTTP请求头 | 浏览器自动带的 |

三个必须同时匹配 ,才能通过验证。

Referer 的作用

Referer 是 HTTP 请求头的一部分,告诉服务器"这个请求是从哪个页面发起的"。

复制代码
浏览器发送POST请求时,会自动带上Referer头:
Referer: http://127.0.0.1:8000/login/

为什么 Django 要检查 Referer?

这是为了防止 跨站请求伪造(CSRF)攻击 :

攻击场景

假设你已登录银行网站 bank.com ,并且银行网站没有 CSRF 保护:

  1. 你访问了一个恶意网站 hacker.com

  2. 恶意网站用你的身份发送请求到 bank.com/transfer?to=hacker&money=10000

  3. 因为浏览器自动带上 Cookie,银行服务器以为是你本人操作

Django 的防护

Django 要求:

  • 请求必须来自 同一个域名 (通过 Referer 判断)

  • 请求必须携带 正确的 Token

这样,即使恶意网站能诱导浏览器发送请求:

  • 没有正确的 csrfmiddlewaretoken ,会被拒绝

  • Referer 不是 bank.com ,会被拒绝

问题2:重定向后返回登录页

原因 :

  • 用户名或密码错误

  • 用户类型不匹配

解决方案 :

  • 确认用户存在且密码正确

  • 确保用户类型与注册时一致

问题3:Token过期

原因 :

  • 多次获取Token但只使用一次

  • 每次GET请求都会生成新Token

解决方案 :

  • 每次登录前只GET一次Token

  • 使用同一个Session完成整个流程

相关推荐
minglie12 小时前
人的性质辨析
学习
IMPYLH2 小时前
Linux 的 stty 命令
linux·运维·服务器·python·bash
hnxaoli2 小时前
win10小程序(十九)鼠标位置记录
python·小程序
步辞2 小时前
React 自定义 Hook 的命名规范与执行上下文详解
jvm·数据库·python
wangcheng3032 小时前
人在回路如何让智能系统更可靠
笔记
forEverPlume2 小时前
如何为 Go 中的 sync.WaitGroup.Wait() 添加超时机制
jvm·数据库·python
踏歌~2 小时前
Qlib上手指南
python·qlib
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年4月26日
大数据·人工智能·python·信息可视化·自然语言处理
2401_883600252 小时前
mysql如何设置仅允许特定内网访问_MySQL权限配置中的IP绑定
jvm·数据库·python