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 的字符。
我使用 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 的字符。