Twitter API Post 请求 -- 错误代码 215 错误的身份验证数据

Twitter API Post Request -- Error Code 215 Bad Authentication data

我正在用 MicroPython 在 NodeMCU ESP8266 开发板上 运行 构建一个 Twitter 机器人。 MicroPython 不支持开箱即用的 OAuth 1.0 请求,所以我不得不自己动手。 我一直在关注这些 write-ups 来构建我的程序:

  1. https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/authorizing-a-request
  2. 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 条目。瞧,当我从字典中删除该键时,错误消失了。

请参阅上面的代码库。