C# 获取Twitter请求令牌失败

C# 获取Twitter请求令牌失败,c#,oauth,twitter-oauth,C#,Oauth,Twitter Oauth,我按照at的指示,开发了一个c#类来执行OAuth授权我使用了页面上的参数,输出签名基字符串和签名与页面上的匹配。因此,我认为算法部分是正确的。然后我用我的twitter应用程序中的参数替换了参数,但我未能从twitter服务获取请求令牌。响应数据为“未能验证oauth签名和令牌” 以下是我发送的请求(我使用http而不是https进行调试): 以下是回应: HTTP/1.1 401 Unauthorized Connection: Keep-Alive Connection: Proxy-Su

我按照at的指示,开发了一个c#类来执行OAuth授权我使用了页面上的参数,输出签名基字符串和签名与页面上的匹配。因此,我认为算法部分是正确的。然后我用我的twitter应用程序中的参数替换了参数,但我未能从twitter服务获取请求令牌。响应数据为“未能验证oauth签名和令牌”

以下是我发送的请求(我使用http而不是https进行调试):

以下是回应:

HTTP/1.1 401 Unauthorized
Connection: Keep-Alive
Connection: Proxy-Support
Content-Length: 44
Via: 1.1 APS-PRXY-09
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Date: Fri, 08 Apr 2011 05:47:20 GMT
Content-Type: text/html; charset=utf-8
Server: hi
Proxy-Support: Session-Based-Authentication
Status: 401 Unauthorized
X-Transaction: 1302241640-40339-46793
Last-Modified: Fri, 08 Apr 2011 05:47:20 GMT
X-Runtime: 0.01519
Pragma: no-cache
X-Revision: DEV
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Set-Cookie: k=207.46.55.29.1302241640766556; path=/; expires=Fri, 15-Apr-11 05:47:20 GMT; domain=.twitter.com
Set-Cookie: guest_id=13022416407746962; path=/; expires=Sun, 08 May 2011 05:47:20 GMT
Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCEiBpjMvAToHaWQiJWMzMTViOGZiNDkzMDRi%250ANjNhMmQwYmVkZDBhNTc2NTc4IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--177afd5c0f6fe30005ab9a9412e6f85ab03cbfa7; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding

Failed to validate oauth signature and token
这就是我如何生成规范化参数的方法:

string.Join("&", (from d in this.BuildParameterDict()
                  select string.Format("{0}={1}", OAuthEncoding.Encode(d.Key), OAuthEncoding.Encode(d.Value))))
BuildParameterDict方法将使用以下内容构建一个列表:来自查询字符串的参数;来自人体的参数;参数sepcific为“oauth”,但“oauth_签名”除外

然后,通过以下方式生成签名基字符串:

            StringBuilder sb = new StringBuilder();

            sb.Append(OAuthEncoding.Encode(this._request.Method));
            sb.Append('&');
            sb.Append(OAuthEncoding.Encode(this.GetNormalUri()));
            sb.Append('&');
            sb.Append(OAuthEncoding.Encode(this.GetNormalParameters()));
这是生成的基本字符串,带有上面页面中的参数:

POST&https%3A%2F%2Fapi.twitter.com%2fauth%2request_token&oauth_callback%3Dhttp%253A%252F%252Flocalhost%253A3005%252F进程_callback%253F服务_provider_id%253D11%26oauth_消费者_密钥%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3DQP70ENMVZ8JVDPEVU3OJD7R7ODC2XN4XLJJUK%26oauth签名时间戳%3DQ23%23042%26oauth_版本%3D1.0


与该页上的字符串相同。

您的oauth签名在请求中列为“oauth\u signagure”

oAuth参数在发送之前必须进行排序,但签名必须在授权请求的末尾。(9.1.1 in)

您可能还需要指定realm=“/oauth/request\u token”。这是可选的,但正如我正确地记得的,Twitter希望将此作为请求令牌


如果您可以添加代码,我们可能会发现发生了什么,因为您可能没有正确构建签名哈希的请求和密钥。

感谢您找到了这个输入错误:)我将在原始帖子中添加一些代码片段。是的,您是对的。“oauth_签名”必须排在最后。但是没有提到,这个例子甚至是错误的……我讨厌推特:(oauth参数是请求参数,它们不在授权标头中。将它们放在标头下面。但是根据,我可以使用“授权”标头。此外,我尝试将它们放在正文中,也不起作用…您的基本字符串似乎没有问题。您的哈希处理如何?您在创建签名时使用了什么?密钥需要更改。)由OAUTH_CONSUMER_SECRET和OAUTH_TOKEN构造。即使令牌缺少密钥,但密钥的结尾需要有一个&值(代码为PHP):
$key=$OAUTH_CONSUMER_SECRET.&.$OAUTH_TOKEN;
比签名
$OAUTH_signature=base64_encode(hash_hmac('sha1',$BASE_STRING,$key,true));
…我猜您的签名有问题。此外,您正在创建的字符串似乎“完全正确”Twitter的例子也是如此。你不是自己创建一个nonce和时间戳吗?你是使用手写字符串吗?你必须提供unixtime形式的时间戳,并且nonce必须是随机的。类似于md5散列一个随机的大数字……是的,“&”已经解决了。在上面的代码中,我在实践中硬编码了“timespan”和“nonce”用适当的值替换y。
            StringBuilder sb = new StringBuilder();

            sb.Append(OAuthEncoding.Encode(this._request.Method));
            sb.Append('&');
            sb.Append(OAuthEncoding.Encode(this.GetNormalUri()));
            sb.Append('&');
            sb.Append(OAuthEncoding.Encode(this.GetNormalParameters()));