根本原因是requests.Session缺乏按域名分发凭证的能力,它只维护全局认证策略,导致cookie与auth互斥;正确做法是为每种认证方式创建独立Session实例并严格绑定域名。
requests 中混用 cookie 和 token 会静默失效
根本原因不是你配错了,而是 requests.session 没有“按域名分发凭证”的能力——它只维护一套全局认证策略。一旦你给同一个 session 实例既设了 session.auth(比如 ('user', 'pass')),又手动塞了 session.cookies.set(),后者会被前者压制:后续请求压根不带 cookie 头。
- 现象:对
admin.internal发请求,返回 401 或跳登录页;抓包发现请求里没Cookie字段 - 本质:HTTP 客户端库(包括 requests、curl、axios)都把 auth 和 cookie 当作互斥的凭证通道
- 正确做法:为每种认证方式创建独立
Session实例,并严格绑定域名
用两个 Session 实例隔离 cookie 和 config 认证
这不是“切换配置”,而是“实例级隔离”。比如一个服务靠表单登录后发 Set-Cookie 维持会话,另一个 API 明确要求 Authorization: Bearer xxx,它们必须走不同的 Session。
-
cookie_session = requests.Session():只负责admin.internal类服务,手动注入 cookie:cookie_session.cookies.set('sessionid', 'abc123', domain='admin.internal') -
token_session = requests.Session():只负责api.example.com类服务,设 header:token_session.headers['Authorization'] = 'Bearer xxx'(别用auth=) - 后续所有请求必须严格对应:用
cookie_session.get('https://admin.internal/...'),用token_session.get('https://api.example.com/...')
curl 脚本里不能拼参数,得靠 shell 分支选认证方式
curl -u user:pass --cookie "sid=xxx" https://host/ 这种写法注定失败——-u 会强制发送 Authorization 头并屏蔽 Cookie 头,且 cookie 域名未限定,可能泄露到错误站点。
- 正确思路:用变量存认证参数,再用
case或if匹配 URL 域名 - 例如:
TOKEN_AUTH="-H 'Authorization: Bearer abc'",COOKIE_AUTH="--cookie 'sessionid=def; Domain=admin.internal'" - 调用时只传一个:
curl $TOKEN_AUTH https://api.example.com/或curl $COOKIE_AUTH https://admin.internal/
跨域场景下 Cookie 的 Domain 和 SameSite 必须显式设置
即使你用了独立 Session,如果服务端下发的 Set-Cookie 缺少关键属性,浏览器根本不会在后续请求中带上它——尤其当前端和后端域名不完全相同时(如 app.example.com → api.example.com)。
-
Domain必须带点前缀,如.example.com,才能被子域共享 -
SameSite必须设为None,否则跨站请求不携带 Cookie -
Secure必须为true(即仅 HTTPS),否则SameSite=None会被浏览器拒绝 - PHP 示例:
setcookie('session_id', 'abc123', ['domain' => '.example.com', 'samesite' => 'None', 'secure' => true, 'httponly' => true])


















