python 在 Twitter OAuth POST 请求上获取 401

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/688766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:38:31  来源:igfitidea点击:

Getting 401 on Twitter OAuth POST requests

pythonweb-servicestwitterrestoauth

提问by Baishampayan Ghose

I am trying to use Twitter OAuth and my POSTrequests are failing with a 401(Invalid OAuth Request) error.

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

For example, if I want to post a new status update, I am sending a HTTP POSTrequest to https://twitter.com/statuses/update.jsonwith the following parameters -

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

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`

My GETrequests are all working fine. I can see on the mailing lists that a lot of people have had identical problems but I could not find a solution anywhere.

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

I am using the oauth.pyPython library.

我正在使用oauth.pyPython 库。

采纳答案by Zain Shaikh

Most likely, the signature is invalid. You must follow the OAuth spec on how to generate the signature( normalized parameters, URLencoding, and cosumerSecret&oauthScret. More on this later ......

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

回答by Baishampayan Ghose

I just finished implementing twitter OAuth API from scratch using Java. Get and post requests work OK. You can use this page http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.htmlto check signature and HTTP headers. Just enter your keys and tokens and check output. It seems twitter works exactly as described on this post. Be careful with spaces and UTF-8 symbols, for example Java encodes space as "+" but OAuth requires %20

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

回答by Nobu

Make sure your app access type is read & write. On your app settings page (ex. http://twitter.com/apps/edit/12345) there's a radio button field like this:

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

Default Access type: Read & Write / Read-only

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

If you check 'Read-only' then status update API will return 401.

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

回答by user560636

I second the answer by Jrgns. I has exactly the same issue. When reading the example Twitter provides, it's actually clear. However their pseudo code is misleading. In Python this worked for me :

我支持 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

回答by Jrgns

I had the same issues, until I realised that the parameters need to be encoded twice for the base string. My GET requests all worked fine, but my POSTs, particularly status updates, failed. On a hunch I tried a POST without spaces in the statusparameter, and it worked.

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

In PHP:

在 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));

Notice the encodefunction around the names and values of the parameters, and then around the whole query string. A Space should end up as %2520, not just %20.

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

回答by Zain Shaikh

I found the solution and it works for me, You must add the following paramters in the request header and it should look like following (c# code), donot use & sign, instead separate parameters by comma(,) sign. and you must add the word "OAuth" in the beginging.

我找到了解决方案,它对我有用,您必须在请求标头中添加以下参数,它应该如下所示(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\"";

httpWebRequest.Headers[System.Net.HttpRequestHeader.Authorization] = "OAuth oauth_consumer_key=\"hAnZFaPKxXxXnJqdfLhDikdw\", oauth_nonce=\"4729687\", oauth_signature_method=\"HMAC-SHA1\",28othken\"28uth1\", =\"17596307-KH9iUzqTxaoa5576VjILkERgUxcqExRyXkfb8AsXy\", oauth_version=\"1.0\", oauth_signature=\"p8f5WTObefG1N9%2b8AlBji1d";

and other parameters like 'status' should be written in the body of the request.

和其他参数如“状态”应该写在请求的正文中。