【问题标题】:Getting 401 on Twitter OAuth POST requests在 Twitter OAuth POST 请求上获取 401
【发布时间】:2010-10-15 21:11:54
【问题描述】:

我正在尝试使用 Twitter OAuth,但我的 POST 请求失败并出现 401 (Invalid OAuth Request) 错误。

例如,如果我想发布新的状态更新,我将使用以下参数向https://twitter.com/statuses/update.json 发送 HTTP POST 请求 -

status=Testing&oauth_version=1.0&oauth_token=xxx&
oauth_nonce=xxx&oauth_timestamp=xxx&oauth_signature=xxx&
oauth_consumer_key=xxx&in_reply_to=xxx&oauth_signature_method=HMAC-SHA1`

我的GET 请求一切正常。我可以在邮件列表中看到很多人都遇到过相同的问题,但我在任何地方都找不到解决方案。

我正在使用oauth.py Python 库。

【问题讨论】:

  • 当您尝试使用 http 而不是 https 时是否有效?只是为了确定问题
  • 我遇到了同样的问题,结果我的应用在 Twitter 上的配置中的“回调 URL”部分不知何故被清除了。当它为空时,它会进入桌面模式并阻止使用动态回调的能力。您可以将任何占位符文本放在您想要的设置中,只要它不为空即可。
  • @JeffStanden 谢谢,解决了我的 Twitter 身份验证问题。

标签: python web-services twitter rest oauth


【解决方案1】:

我刚刚使用 Java 从头开始​​实现了 twitter OAuth API。获取和发布请求工作正常。您可以使用此页面http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html 来检查签名和 HTTP 标头。只需输入您的密钥和令牌并检查输出。看来 twitter 的工作方式与这篇文章中描述的完全一样。注意空格和 UTF-8 符号,例如 Java 将空格编码为“+”,但 OAuth 需要 %20

【讨论】:

    【解决方案2】:

    确保您的应用访问类型为读写。 在您的应用设置页面(例如http://twitter.com/apps/edit/12345)上有一个单选按钮字段,如下所示:

    默认访问类型:读写/只读

    如果您选中“只读”,则状态更新 API 将返回 401。

    【讨论】:

      【解决方案3】:

      我支持 Jrgns 的回答。我有完全相同的问题。阅读 Twitter 提供的示例时,实际上很清楚。然而,他们的伪代码具有误导性。在 Python 中,这对我有用:

      def encodekeyval(key, val):
          key = urllib.quote(key, '')
          val = urllib.quote(val, '')
          return urllib.quote(key + '=' + val, '')
      
      def signature_base_string(urlstr, oauthdata):
          sigstr = 'POST&' + urllib.quote(urlstr,'') + '&'
          # retrieve "post" data as dictionary of name value pairs
          pdata = oauthdata.getpdata()
          # need to sort parameters
          pstr = '%26'.join([encodekeyval(key, pdata[key]) for key in sorted(pdata.keys())])
          return sigstr + pstr
      

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,直到我意识到参数需要为基本字符串编码两次。我的 GET 请求一切正常,但我的 POST,尤其是状态更新,失败了。凭直觉,我尝试了一个在 status 参数中没有空格的 POST,它成功了。

        在 PHP 中:

        function encode($input) {
            return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
        }
        
        $query = array();
        foreach($parameters as $name => $value) {
            $query[] = encode($name) . '=' .encode($value);
        }
        $base = encode(strtoupper($method)) . '&' .encode($norm_url) . '&' . 
        encode(implode('&', $query));
        

        注意encode 函数围绕参数的名称和值,然后围绕整个查询字符串。空格应以%2520 结尾,而不仅仅是%20

        【讨论】:

        • 也许这只是拯救了我的一天。我遇到了完全相同的问题,只是在 JavaScript 中。 GET 工作,POST 没那么多...
        【解决方案5】:

        我找到了解决方案,它对我有用,您必须在请求标头中添加以下参数,它应该如下所示(c# 代码),不要使用 & 符号,而是用逗号(,)符号分隔参数。并且您必须在开头添加单词“OAuth”。

        httpWebRequest.Headers[System.Net.HttpRequestHeader.Authorization] = "OAuth oauth_consumer_key=\"hAnZFaPKxXnJqdfLhDikdw\", oauth_nonce=\"4729687\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1284821989\ ", oauth_token=\"17596307-KH9iUzqTxaoa5576VjILkERgUxcqExRyXkfb8AsXy\", oauth_version=\"1.0\", oauth_signature=\"p8f5WTObefG1N9%2b8AlBji1pg18A%3d\"";

        其他参数如“状态”应写入请求正文中。

        【讨论】:

          【解决方案6】:

          很可能,签名无效。您必须遵循 OAuth 规范关于如何生成签名(规范化参数、URLencoding 和 cosumerSecret&oauthScret。稍后会详细介绍......

          【讨论】:

          • 稍后?稍后何时/何地?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-10
          • 2017-03-14
          • 2013-05-13
          • 2016-03-29
          • 1970-01-01
          相关资源
          最近更新 更多