Python Requests调用DRF接口提示未提供身份验证凭证如何解决
问题解答
1. GET请求是否需要携带CSRF Token?
Django默认仅对非安全请求(POST、PUT、DELETE、PATCH等)校验CSRF,GET、HEAD、OPTIONS这类只读的安全请求不需要校验CSRF,你遇到的Authentication credentials were not provided报错和CSRF无关,核心原因是请求未携带有效的用户身份凭证。
2. 已登录用户身份传递方案
你用的SessionAuthentication依赖Django的会话Cookie识别用户身份,你当前用requests发的请求是无状态的,没有携带用户的sessionid Cookie,所以DRF无法识别用户身份,根据你的使用场景可以选择对应方案:
场景1:函数运行在Django服务内部(用户访问Django视图时触发调用)
这种情况优先建议你把DRF接口的业务逻辑抽成公共方法,直接调用即可,不需要额外发HTTP请求损耗性能。如果一定要通过HTTP请求调用接口,把当前请求的sessionid Cookie携带到新请求里即可:
def get_car_details(car_id, request): headers = {"X-Requested-With": "XMLHttpRequest"} # 携带当前登录用户的session cookie cookies = {"sessionid": request.COOKIES.get("sessionid")} api_app = "http://localhost:8000/" api_model = "cars/" response = requests.get( api_app + api_model + str(car_id), headers=headers, cookies=cookies ) return response.json()
调用时传入Django视图的request对象即可。
场景2:函数作为独立脚本运行
先初始化requests的Session实例,完成登录后所有请求都通过Session实例发送,会自动携带会话Cookie:
import requests # 全局初始化Session实例,复用会话状态 req_session = requests.Session() # 先完成登录操作,示例登录逻辑 login_url = "http://localhost:8000/accounts/login/" # 先访问登录页获取CSRF Token req_session.get(login_url) login_data = { "username": "你的账号", "password": "你的密码", "csrfmiddlewaretoken": req_session.cookies.get("csrftoken") } # 提交登录 req_session.post(login_url, data=login_data) # 后续接口请求都用req_session发送 def get_car_details(car_id): headers = {"X-Requested-With": "XMLHttpRequest"} api_app = "http://localhost:8000/" api_model = "cars/" response = req_session.get(api_app + api_model + str(car_id), headers=headers) return response.json()
补充说明
如果后续需要发送POST/PUT等修改类请求,需要在请求头中添加X-CSRFToken字段,值为Cookie中存储的csrftoken值即可。
内容的提问来源于stack exchange,提问作者Hanny
相关产品推荐
相关产品推荐

