使用Requests自定义Auth时Session无法持久化Cookie问题求助
我正尝试通过JSON交互登录某Web服务,并参考requests官方文档实现自定义认证机制,代码如下:
import requests class Testauth(requests.auth.AuthBase): """Implements a custom authentication scheme.""" def __init__(self, email, passwd): loginjson = {"Data":{"EMAIL":email,"PASSWORD":passwd}} req = requests.post('https://httpbin.org/post', json=loginjson) self.token = req.json()['data'] #原服务为: ['Data'][0]['SESSION_ID'] def __call__(self, r): """Attach an API token to a custom auth header.""" r.prepare_cookies({'SESSION_ID' : f'{self.token}'}) # Python 3.6+ return r curSession = requests.Session() curSession.auth=Testauth('email','pass') page = curSession.get('https://httpbin.org/get') print(curSession.cookies) print(page.content.decode('utf-8'))
我原本预期,当通过auth方法访问/get接口完成认证后,curSession应该会保存对应的Cookie,但检查发现curSession.cookies为空,只有请求本身携带了Cookie。根据requests官方文档说明,Session应在请求间持久化Cookie,但实际并未生效,请问我哪里操作有误?
摘要:
使用Session时,自定义认证无法在Session中持久化Cookie,每次请求都会生成新的认证Cookie
问题根源
- 登录请求未通过Session发送:
Testauth初始化时直接调用requests.post(),而非使用Session的post()方法,导致登录返回的Cookie无法被Session的CookieJar捕获。 - 手动附加Cookie未写入Session:
__call__方法里的r.prepare_cookies()仅为当前请求添加Cookie,并未将其存入Session的cookies对象,所以Session不会持久化该Cookie。
修复代码
import requests class Testauth(requests.auth.AuthBase): """Implements a custom authentication scheme.""" def __init__(self, session, email, passwd): # 传入Session,用它发送登录请求,让Cookie自动存入Session的CookieJar loginjson = {"Data":{"EMAIL":email,"PASSWORD":passwd}} req = session.post('https://httpbin.org/post', json=loginjson) # 从登录响应中获取SESSION_ID(原服务逻辑:req.json()['Data'][0]['SESSION_ID']) self.session_id = req.json()['data'] # 手动存入Cookie(如果登录响应未自动设置Cookie时用这步) session.cookies.set('SESSION_ID', self.session_id) def __call__(self, r): # Session已持有Cookie,无需再手动附加 return r curSession = requests.Session() # 初始化认证时传入Session对象 Testauth(curSession, 'email','pass') page = curSession.get('https://httpbin.org/get') print(curSession.cookies) print(page.content.decode('utf-8'))
补充说明
- 若需要在每次请求前校验Cookie有效性,可在
__call__方法中添加逻辑:检查Session中是否存在有效Cookie,失效则重新登录并更新CookieJar。 - 只有通过Session发送的请求才会共享CookieJar,直接使用
requests.get/post()的请求不会复用Session的Cookie。
内容的提问来源于stack exchange,提问作者ulasfo
相关产品推荐
相关产品推荐

