如何在Python requests模块中同时使用Basic Auth与Bearer Token Auth
问题
如何在Python requests模块中同时使用Basic Auth与Bearer Token Auth?
背景
我编写了一段curl脚本,希望用Python requests模块实现相同功能:
curl --location --request POST 'https://username@password:example.com/path/to/endpoint' \ --header 'Authorization: Bearer SOME_TOKEN' \ --header 'Content-Type: application/json' \ --data-raw '{ "example": "example" }'
对应的Python代码如下:
import requests import json url = "https://username@password:example.com/path/to/endpoint" payload = json.dumps({ "example": "example" }) headers = { 'Authorization': 'Bearer SOME_TOKEN', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload)
但这段代码未达到预期效果,捕获到的HTTP请求中出现了Authorization: Basic xxxxx,而非预期的Authorization: Bearer SOME_TOKEN。
问题原因
- URL格式错误:正确的Basic Auth URL格式应为
https://用户名:密码@域名,你当前的写法https://username@password:example.com会导致requests解析异常。 - 头覆盖问题:requests会自动将URL中包含的用户名密码转换为
Authorization: Basic头,这会直接覆盖你在headers中定义的Bearer Token头。
解决方案
方案一:使用auth参数传递Basic Auth(推荐)
这种方式既规范又能避免头覆盖问题,requests会正确处理Basic Auth认证,同时保留自定义的Bearer Token头:
import requests import json url = "https://example.com/path/to/endpoint" payload = json.dumps({ "example": "example" }) headers = { 'Authorization': 'Bearer SOME_TOKEN', 'Content-Type': 'application/json' } # 通过auth参数传入Basic Auth的用户名和密码 response = requests.request("POST", url, headers=headers, data=payload, auth=("username", "password"))
方案二:手动构造多Authorization头(仅适用于支持多认证头的服务器)
如果服务器允许同时接收两个Authorization头,可以手动构造Basic Auth头并以列表形式传入headers(字典会覆盖同名key,因此需用列表):
import requests import json import base64 # 对Basic Auth的用户名密码进行Base64编码 username = "username" password = "password" basic_auth_str = base64.b64encode(f"{username}:{password}".encode()).decode() url = "https://example.com/path/to/endpoint" payload = json.dumps({ "example": "example" }) # 用列表形式定义多个Authorization头 headers = [ ('Authorization', 'Bearer SOME_TOKEN'), ('Authorization', f'Basic {basic_auth_str}'), ('Content-Type', 'application/json') ] response = requests.request("POST", url, headers=headers, data=payload)
附录说明
requests模块完全支持URL中的Basic Auth格式(https://username:password@example.com),但该方式会自动生成Basic Auth头,若同时自定义Authorization头会被覆盖,因此不推荐在URL中携带认证信息。
内容的提问来源于stack exchange,提问作者Kohei Yasan
相关产品推荐
相关产品推荐

