Twitter API Post 请求 -- 错误代码 215 错误的身份验证数据
Twitter API Post Request -- Error Code 215 Bad Authentication data
我正在用 MicroPython 在 NodeMCU ESP8266 开发板上 运行 构建一个 Twitter 机器人。 MicroPython 不支持开箱即用的 OAuth 1.0 请求,所以我不得不自己动手。
我一直在关注这些 write-ups 来构建我的程序:
- https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/authorizing-a-request
- https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/creating-a-signature
每当我向 send a tweet 发送 POST 请求时,我都会收到以下错误响应:{"errors":[{"code":215,"message":"Bad Authentication data."}]}
.
我为 MicroPython urequests
模块编写了一个小包装器 class,名为 oauth_requests
import urequests as requests
class oauth_request:
@classmethod
def post(cls, url, params, key_ring):
""" Post method with OAuth 1.0
Args:
url (str): URL to send request to.
params (dict): Params to append to URL.
key_ring (dict): Dictionary with API keys.
Returns:
Response from POST request.
"""
auth_header = cls.__create_auth_header("POST", url, params, **key_ring)
headers = {"Authorization": auth_header}
url += "?{}".format(
"&".join([
"{}={}".format(cls.__percent_encode(str(k)), cls.__percent_encode(str(v)))
for k, v in params.items()
]))
return requests.post(url, headers=headers)
cls.__create_auth_header(...)
的 return 值是一个“OAuth”字符串,就像上面 link #1 末尾的字符串一样。我已经验证了我的 HMAC-SHA1
算法的实现从上面 link #2 中的样本数据产生了相同的输出。我能够通过 PostMan 发送相同的响应,所以我的 API 密钥有效。
我是否错误地创建了请求headers?
我已将我的代码提交给 this 存储库。
我最终找到了解决问题的方法。主要问题是我没有对 oauth_signature
的值进行百分比编码。然而,即使在那之后我还是收到了一个新的错误,{"errors":[{"code":32,"message":"Could not authenticate you."}]}
。
从我最初在上面发布的关于 creating the signature 的 link 中,您可以从百分比编码构建基本参数字符串,然后“&”加入 oauth
字典,如下所示:
url_params = {
"status": "Tweeting from the future."
}
oauth = {
"include_entities": "true",
"oauth_consumer_key": consumer_key,
"oauth_nonce": generate_nonce(),
"oauth_signature_method": "HMAC-SHA1",
"oauth_timestamp": 946684800 + time.time(),
"oauth_token": access_token,
"oauth_version": 1.0,
}
oauth.update(url_params)
base_string = percent_encode_and_join(oauth)
(时间值是奇数,因为micropython系统时间纪元开始于2000年1月1日,而不是1970年1月1日)
然而,当我使用 PostMan 调试请求时,它工作正常。我意识到 Postman 在计算签名时不知道添加 include_entities
条目。瞧,当我从字典中删除该键时,错误消失了。
请参阅上面的代码库。
我正在用 MicroPython 在 NodeMCU ESP8266 开发板上 运行 构建一个 Twitter 机器人。 MicroPython 不支持开箱即用的 OAuth 1.0 请求,所以我不得不自己动手。 我一直在关注这些 write-ups 来构建我的程序:
- https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/authorizing-a-request
- https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/creating-a-signature
每当我向 send a tweet 发送 POST 请求时,我都会收到以下错误响应:{"errors":[{"code":215,"message":"Bad Authentication data."}]}
.
我为 MicroPython urequests
模块编写了一个小包装器 class,名为 oauth_requests
import urequests as requests
class oauth_request:
@classmethod
def post(cls, url, params, key_ring):
""" Post method with OAuth 1.0
Args:
url (str): URL to send request to.
params (dict): Params to append to URL.
key_ring (dict): Dictionary with API keys.
Returns:
Response from POST request.
"""
auth_header = cls.__create_auth_header("POST", url, params, **key_ring)
headers = {"Authorization": auth_header}
url += "?{}".format(
"&".join([
"{}={}".format(cls.__percent_encode(str(k)), cls.__percent_encode(str(v)))
for k, v in params.items()
]))
return requests.post(url, headers=headers)
cls.__create_auth_header(...)
的 return 值是一个“OAuth”字符串,就像上面 link #1 末尾的字符串一样。我已经验证了我的 HMAC-SHA1
算法的实现从上面 link #2 中的样本数据产生了相同的输出。我能够通过 PostMan 发送相同的响应,所以我的 API 密钥有效。
我是否错误地创建了请求headers?
我已将我的代码提交给 this 存储库。
我最终找到了解决问题的方法。主要问题是我没有对 oauth_signature
的值进行百分比编码。然而,即使在那之后我还是收到了一个新的错误,{"errors":[{"code":32,"message":"Could not authenticate you."}]}
。
从我最初在上面发布的关于 creating the signature 的 link 中,您可以从百分比编码构建基本参数字符串,然后“&”加入 oauth
字典,如下所示:
url_params = {
"status": "Tweeting from the future."
}
oauth = {
"include_entities": "true",
"oauth_consumer_key": consumer_key,
"oauth_nonce": generate_nonce(),
"oauth_signature_method": "HMAC-SHA1",
"oauth_timestamp": 946684800 + time.time(),
"oauth_token": access_token,
"oauth_version": 1.0,
}
oauth.update(url_params)
base_string = percent_encode_and_join(oauth)
(时间值是奇数,因为micropython系统时间纪元开始于2000年1月1日,而不是1970年1月1日)
然而,当我使用 PostMan 调试请求时,它工作正常。我意识到 Postman 在计算签名时不知道添加 include_entities
条目。瞧,当我从字典中删除该键时,错误消失了。
请参阅上面的代码库。