Python requests库调用Specify7 API返回403错误求助
问题根因
代码核心问题是没有维持会话状态,第二次登录请求没带上第一次请求返回的Cookie。
Specify7后端基于Django框架开发,CSRF校验采用双重匹配逻辑:
- 必须同时满足请求头
X-CSRFToken的值、Cookie中存储的csrftoken值完全一致 - 登录流程依赖Cookie中的会话ID关联请求上下文
你写的两次请求是完全独立的:第一次GET拿到CSRF token之后,响应头里带的Set-Cookie内容根本没传到第二次PUT请求里,后端收不到对应Cookie,直接判定校验失败返回403。
还有两个高频触发403的细节问题:
Referer字段必须是和服务端同源的全路径地址,仅传根域名会被判定为非法跨域请求- 部分版本的Specify7登录接口仅接收表单格式参数,不识别JSON格式的请求体
修复方案
使用requests.Session()对象自动维护整个请求流程的Cookie,无需手动处理Cookie传递逻辑:
import requests # 初始化会话对象,自动持久化所有请求的Cookie session = requests.Session() # 替换为实际部署的Specify7服务地址 base_url = "http://your-specify7-service-address" login_url = f"{base_url}/accounts/login/" # 第一步:访问登录页,csrftoken会自动写入会话Cookie session.get(login_url) csrf_token = session.cookies.get("csrftoken") print("获取到的CSRF Token:", csrf_token) # 第二步:构造请求头,Referer要写完整的登录页地址 headers = { "X-CSRFToken": csrf_token, "Referer": login_url } login_data = { "username": "testy", "password": "redacted", "collection": 4 } # 如果用data=login_data仍报403,可替换为json=login_data适配不同版本接口 resp = session.put(login_url, data=login_data, headers=headers) print("响应状态码:", resp.status_code) # 后续调用其他业务接口都复用该session对象即可,会自动携带合法Cookie
排障检查项
修复后仍返回403可逐一核对:
- 确认
collection对应的ID是当前登录账号有权限访问的集合ID - 若服务端开启了Origin校验,可在headers中补充
Origin: base_url字段 - 确认账号密码输入正确,账号无锁定、权限限制
内容的提问来源于stack exchange,提问作者Fedor Steeman
相关产品推荐
相关产品推荐

