Unicode-objects 在 python3 中散列之前必须编码
Unicode-objects must be encoded before hashing in python3
我一直在尝试制作一个与 MKM 的 API 交互的应用程序,但我决定不使用 OAuth1 库并自己制作 headers,但我遇到了问题带有 Oauth1 需要的签名。整个过程(for php)可见here.
这是我目前拥有的代码(我正在通过尝试发送单个请求来测试 API,这样我就可以看到它是如何工作的)
代码:
#!/usr/bin/env python3
import requests
from urllib.parse import quote_plus as rawurlencode
import time
import string
import random
import operator
import uuid
from hashlib import sha1
from hmac import new as hmac
#check this
def main():
app_token = "XXXXXXXXX"
app_secret = "XXXXXXXXX"
access_token = "XXXXXXXXX"
access_token_secret = "XXXXXXXXX"
signing_key = str(app_secret+'&'+access_token_secret)
nonce = uuid.uuid4().hex
url = 'https://api.cardmarket.com/ws/v2.0/account'
base_url='GET&'+rawurlencode(url)+'&'
params = 'oauth_consumer_key=XXXXXXXXX&'+ \
'oauth_nonce='+nonce+'&'+\
'oauth_signature_method="HMAC-SHA1&'+\
'oauth_timestamp='+str(int(time.time()))+'&'+\
'oauth_token=XXXXXXXXX&'+\
'oauth_version=1.0'
base_string = rawurlencode(params)
string_f = base_url+base_string
signature = hmac(signing_key.encode('utf-8'), base_string, sha1).digest().encode('base64')[:-1]
MyHeader = 'OAuth ' + 'realm="' + url + '", '
MyHeader += 'oauth_consumer_key' + '="' + 'XXXXXXXXX' + '",'
MyHeader += 'oauth_nonce' + '="' + nonce + '",'
MyHeader += 'oauth_signature_method' + '="' + 'HMAC-SHA1' + '",'
MyHeader += 'oauth_timestamp' + '="' + str(int(time.time())) + '",'
MyHeader += 'oauth_token' + '="' + 'XXXXXXXXX' + '",'
MyHeader += 'oauth_version' + '="' + '1.0' + '",'
MyHeader += 'oauth_signature="' + signature +'"'
headers = {'Authorization': MyHeader}
response = request.get(url,headers=headers)
print(response.json())
#print(base_string+"\n\n")
#print("KEY "+signing_key+"\n\n")
#print("String final "+string_f+"\n\n")
if __name__ == "__main__":
main()
当我使用脚本时,我收到下一条消息:
Traceback (most recent call last):
File "origin.py", line 58, in <module>
main()
File "origin.py", line 36, in main
signature = hmac(signing_key.encode('utf-8'), base_string, sha1).digest().encode('base64')[:-1]
File "/usr/lib/python3.6/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.6/hmac.py", line 84, in __init__
self.update(msg)
File "/usr/lib/python3.6/hmac.py", line 93, in update
self.inner.update(msg)
TypeError: Unicode-objects must be encoded before hashing
现在,我一直在研究这个问题,我在 HMAC 构造函数上尝试了不同的方法,所以它不会失败,我什至将构造函数和 digest() 分开,这样我可以更准确地查明错误在哪里。话虽如此,我已经 运行 没主意了,我已经阅读了大约 100 篇关于这个特定 TypeError 的不同帖子,我真的不知道该怎么做了,这可能会是一件非常愚蠢的事情,但是伙计们,我真的需要你们的帮助,老实说,我有点失去理智了:D
您需要对 base_string
进行编码,因为 hmac 使用的是字节,而不是 unicode 字符串:
signature = hmac(signing_key.encode('utf-8'), base_string.encode(), sha1)
我一直在尝试制作一个与 MKM 的 API 交互的应用程序,但我决定不使用 OAuth1 库并自己制作 headers,但我遇到了问题带有 Oauth1 需要的签名。整个过程(for php)可见here.
这是我目前拥有的代码(我正在通过尝试发送单个请求来测试 API,这样我就可以看到它是如何工作的)
代码:
#!/usr/bin/env python3
import requests
from urllib.parse import quote_plus as rawurlencode
import time
import string
import random
import operator
import uuid
from hashlib import sha1
from hmac import new as hmac
#check this
def main():
app_token = "XXXXXXXXX"
app_secret = "XXXXXXXXX"
access_token = "XXXXXXXXX"
access_token_secret = "XXXXXXXXX"
signing_key = str(app_secret+'&'+access_token_secret)
nonce = uuid.uuid4().hex
url = 'https://api.cardmarket.com/ws/v2.0/account'
base_url='GET&'+rawurlencode(url)+'&'
params = 'oauth_consumer_key=XXXXXXXXX&'+ \
'oauth_nonce='+nonce+'&'+\
'oauth_signature_method="HMAC-SHA1&'+\
'oauth_timestamp='+str(int(time.time()))+'&'+\
'oauth_token=XXXXXXXXX&'+\
'oauth_version=1.0'
base_string = rawurlencode(params)
string_f = base_url+base_string
signature = hmac(signing_key.encode('utf-8'), base_string, sha1).digest().encode('base64')[:-1]
MyHeader = 'OAuth ' + 'realm="' + url + '", '
MyHeader += 'oauth_consumer_key' + '="' + 'XXXXXXXXX' + '",'
MyHeader += 'oauth_nonce' + '="' + nonce + '",'
MyHeader += 'oauth_signature_method' + '="' + 'HMAC-SHA1' + '",'
MyHeader += 'oauth_timestamp' + '="' + str(int(time.time())) + '",'
MyHeader += 'oauth_token' + '="' + 'XXXXXXXXX' + '",'
MyHeader += 'oauth_version' + '="' + '1.0' + '",'
MyHeader += 'oauth_signature="' + signature +'"'
headers = {'Authorization': MyHeader}
response = request.get(url,headers=headers)
print(response.json())
#print(base_string+"\n\n")
#print("KEY "+signing_key+"\n\n")
#print("String final "+string_f+"\n\n")
if __name__ == "__main__":
main()
当我使用脚本时,我收到下一条消息:
Traceback (most recent call last):
File "origin.py", line 58, in <module>
main()
File "origin.py", line 36, in main
signature = hmac(signing_key.encode('utf-8'), base_string, sha1).digest().encode('base64')[:-1]
File "/usr/lib/python3.6/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.6/hmac.py", line 84, in __init__
self.update(msg)
File "/usr/lib/python3.6/hmac.py", line 93, in update
self.inner.update(msg)
TypeError: Unicode-objects must be encoded before hashing
现在,我一直在研究这个问题,我在 HMAC 构造函数上尝试了不同的方法,所以它不会失败,我什至将构造函数和 digest() 分开,这样我可以更准确地查明错误在哪里。话虽如此,我已经 运行 没主意了,我已经阅读了大约 100 篇关于这个特定 TypeError 的不同帖子,我真的不知道该怎么做了,这可能会是一件非常愚蠢的事情,但是伙计们,我真的需要你们的帮助,老实说,我有点失去理智了:D
您需要对 base_string
进行编码,因为 hmac 使用的是字节,而不是 unicode 字符串:
signature = hmac(signing_key.encode('utf-8'), base_string.encode(), sha1)