如何用Python生成Cosmos DB的REST授权令牌?生成时遇问题求助
用Python生成Cosmos DB REST授权令牌及问题修复
我来帮你搞定这个Cosmos DB授权令牌的问题,先理清楚核心逻辑,再排查你代码里的坑~
核心原理
Cosmos DB的REST API授权靠HMAC-SHA256签名实现,生成令牌的关键步骤是:
- 构造严格格式的签名Payload
- 用Cosmos DB主密钥对Payload进行签名
- 将签名结果编码后,拼接成符合要求的Authorization请求头
你的代码问题排查
看了你的代码,有几个关键问题导致签名失败:
- 密钥未解码:你用的主密钥是base64编码的字符串,但HMAC签名需要字节类型的密钥,必须先解码才能用。
- Payload编码缺失:构造的Payload字符串要先转成UTF-8字节再传入HMAC算法,否则会出现编码不匹配的问题。
- Authorization头格式不对:必须严格按照
type=master&ver=1.0&sig=签名值的格式拼接,你可能漏掉了这一步的正确构造。 - 缺少API版本头:Cosmos DB REST请求必须指定
x-ms-version头,否则会直接验证失败。
修正后的完整代码
import requests import hmac import hashlib import base64 from datetime import datetime import locale # 强制生成英文格式的时间(避免系统locale是中文导致星期/月份显示中文) locale.setlocale(locale.LC_TIME, 'en_US.UTF-8') # 替换为你的Cosmos DB主密钥(base64编码字符串) key = 'AG . . .EZPcZBKz7gvrKiXKsuaPA==' # 解码密钥为字节类型 decoded_key = base64.b64decode(key) # 生成UTC时间,严格遵循RFC 1123格式 now = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') # 构造签名Payload:严格按顺序(方法小写→资源路径→空行→Content-Type→日期→空行) # 这里对应GET数据库列表的请求,资源路径是'dbs' payload = ('get\ndbs\n\n' + now + '\n\n').lower() # 生成HMAC-SHA256签名并base64编码 signature = base64.b64encode( hmac.new(decoded_key, msg=payload.encode('utf-8'), digestmod=hashlib.sha256).digest() ).decode('utf-8') # 构造Authorization头 auth_header = f'type=master&ver=1.0&sig={signature}' # 替换为你的Cosmos DB账户URL account_url = 'https://myacct.documents.azure.com:443/' url = f'{account_url}dbs' # 必要的请求头 headers = { 'Authorization': auth_header, 'x-ms-date': now, 'x-ms-version': '2021-05-15' # 可根据需求选择合适的API版本 } # 发送请求 response = requests.get(url, headers=headers) # 查看结果 print(f"响应状态码: {response.status_code}") if response.ok: print("数据库列表:", response.json()) else: print("错误信息:", response.text)
关键注意事项
- 时间格式:必须是UTC时间且为英文RFC 1123格式(如
Mon, 02 Jan 2006 15:04:05 GMT),如果系统默认locale是中文,一定要手动设置成英文,否则签名会验证失败。 - 资源路径:Payload中的资源路径要和请求URL的资源部分完全匹配,比如获取单个数据库的话路径是
dbs/mydb,而不是完整URL。 - API版本:
x-ms-version建议用较新的稳定版本,你可以在Cosmos DB官方文档里查到最新的版本号。
内容的提问来源于stack exchange,提问作者Greg Clinton
相关产品推荐
相关产品推荐

