Postman 为 unicode 密码创建了与 Python 的 base64 模块不同的 base64 值 - 如何解释差异?

Postman creates different base64 value than Python's base64 module for unicode passwords - what explains the difference?

我使用 os.urandom(10) 在 python 中创建了一个随机密码,它创建了一个具有 unicode 值的密码;例如:

>>> import os
>>> os.urandom(10)
'\x8c[A\x91\xf0dq\xb2{\xcc'

在我公司的 ldap 工具中,我将用户的密码设置为该值。

在 Postman 中,我可以通过复制并粘贴该值来创建基本授权 header,并且 成功验证

我尝试了 requests.HTTPBasicAuth,但失败了 UnicodeDecodeError 从另一个问题,我了解到 HTTPBasicAuth 不处理 unicode 值,这是故意的。所以我尝试自己用base64模块来做:

import requests
import base64
...
encoded = base64.b64encode(username + ':' + password)
headers = {'Authorization': 'Basic ' + encoded}
r = requests.post(end_point, headers=headers, verify=False)

然而,这 会产生与 Postman 构建的不同的 base64 编码值。由于授权请求失败。

此外,如果我将 Postman 创建的 base64 编码值复制并粘贴到代码中,则请求有效并且我已成功获得授权。这告诉我 Postman 正在成功地做到这一点。


要自己复制,请打开 Postman 并使用用户名 "username" 和密码“\x8c[A\x91\xf0dq\xb2{\xcc”创建基本身份验证。 Postman 生成以下 64 位编码的字符串:

dXNlcm5hbWU6XHg4Y1tBXHg5MVx4ZjBkcVx4YjJ7XHhjYw==

在 python 中,它执行以下操作:

>>> import base64
>>> username = 'username'
>>> password = '\x8c[A\x91\xf0dq\xb2{\xcc'
>>> base64.b64encode(username + ':' + password)
'dXNlcm5hbWU6jFtBkfBkcbJ7zA=='

造成这些差异的原因是什么,我怎样才能 python 生成与 Postman 相同的值(因为 Postman 生成正确的值?)

python 字符串中的反斜杠是特殊字符,\x 是十六进制转义序列,例如\x8c 是 Œ 的 unicode 字符。看起来您需要显式转义反斜杠才能生成与 Postman 相同的值:

>>> password = '\x8c[A\x91\xf0dq\xb2{\xcc'
>>> base64.b64encode(username + ':' + password)
'dXNlcm5hbWU6XHg4Y1tBXHg5MVx4ZjBkcVx4YjJ7XHhjYw=='

或者将其设为原始字符串:

>>> password = r'\x8c[A\x91\xf0dq\xb2{\xcc'
>>> base64.b64encode(username + ':' + password)
'dXNlcm5hbWU6XHg4Y1tBXHg5MVx4ZjBkcVx4YjJ7XHhjYw=='

您的字符串包含几个典型的转义序列。 Python 将取消转义,除非另有说明。

要定义一个字符串并忽略转义序列,请在其前面放置一个 r。或者,您可以使用双反斜杠。

text = r'\x00'
text = '\x00'

这些都将导致 \x00 而不是转义序列定义的具有 ASCII 代码 0x00 的字符。