Twitter API:POST出现401错误,GET正常工作

3
我已经搜索了几天,但一直无法正确地使用POST到Twitter API。我可以成功获取请求令牌并将其交换为访问令牌,但是当我在statuses/update上做一个POST时,会出现401错误。我已验证头部的授权部分与使用Twitter OAuth工具时收到的完全匹配。我认为我的问题在于我添加状态到web请求正文的方式。URL需要只是https://api.twitter.com/1/statuses/update.json,还是应该是https://api.twitter.com/1/statuses/update.json?status=MyTweetHere?我的代码如下:
        public string UpdateStatus(string requestMethod, string baseUrl, string consumerKey, string consumerSecret, string accessToken, OAuthRequestType requestType, string status)
    {
        //baseUrl = https://api.twitter.com/1/statuses/update.json
        const string signatureMethod = "HMAC-SHA1";
        const string oauthVersion = "1.0";

        var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1));
        var timestamp =  (int)timeSpan.TotalSeconds;

        var nonce = CreateNOnce(timestamp, consumerKey, baseUrl, accessToken);
        var signature = CreateSignature(requestMethod, baseUrl, consumerKey, consumerSecret, nonce, signatureMethod, timestamp, accessToken, oauthVersion, string.Empty, string.Empty, requestType, status);

        var bodyData = "status=" + UrlEncode(status);

        var webRequest = (HttpWebRequest)WebRequest.Create(baseUrl);
        webRequest.KeepAlive = true;
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Method = requestMethod; //Send in as POST
        webRequest.Accept = "*/*";
        webRequest.UserAgent = "Renicorp.Social";

        webRequest.Headers["Authorization"] = "OAuth " + UrlEncode("oauth_consumer_key") + "=\"" + UrlEncode(consumerKey) + "\", " +
                                                         UrlEncode("oauth_nonce") + "=\"" + UrlEncode(nonce) + "\", " +
                                                         UrlEncode("oauth_signature") + "=\"" + UrlEncode(signature) + "\", " +
                                                         UrlEncode("oauth_signature_method") + "=\"" + UrlEncode(signatureMethod) + "\", " +
                                                         UrlEncode("oauth_timestamp") + "=\"" + UrlEncode(timestamp.ToString()) + "\", " +
                                                         UrlEncode("oauth_token") + "=\"" + UrlEncode(accessToken) + "\", " +
                                                         UrlEncode("oauth_version") + "=\"" + UrlEncode(oauthVersion) + "\"";

        string postData = bodyData;
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);

        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.ContentLength = byteArray.Length;

        using (Stream dataStream = webRequest.GetRequestStream())
        {
            dataStream.Write(byteArray, 0, byteArray.Length);
        }

        //Make the web call and return the response
        WebResponse response = webRequest.GetResponse();
        var responseBody = string.Empty;
        Stream stream = response.GetResponseStream();
        if (stream != null) responseBody = new StreamReader(stream).ReadToEnd();
        return responseBody;
    }

更新: 我现在已经编写了一个方法来执行GET操作,用于获取account/verify_credentials.json,并且能够验证帐户凭据,如果使用我的应用程序帐户密钥,但是当我尝试使用另一个帐户并提供访问令牌时,我会收到401错误。


你是否尝试在向流中写入内容之前设置头信息? - Wiktor Zychla
好的,我修改了代码,在添加头之后将数据添加到Web请求的正文中。但我仍然得到了401错误。 - puddinman13
1个回答

1
所以,我的问题出在创建签名密钥时的秘钥。我在twitter应用程序中硬编码了我的秘钥。这就是为什么我的标题总是匹配的,但是当我使用链接的用户帐户运行测试时,请求无法通过。故事的寓意是不要硬编码秘钥。我一直想知道秘钥的作用。现在我知道了。
另外,要使用的URL只是基本URL:https://api.twitter.com/1/statuses/update.json。不需要添加URL参数。最后,在创建HTTP请求正文时,只需“status=UrlEncode(tweetToBeMade)”。

1
干得好!很高兴你解决了它。这个问题真的很难!我正在处理一个类似的任务,需要使用签名请求连接到API,但我还没有成功连接。这真是太痛苦了,所以你做到了真不错。我一次又一次地在绝望中撞墙。:D 但我最终会搞定的。如果有人感兴趣,我也找到了一篇有用的帖子:https://gist.github.com/smockle/5537203。Twitter API规范很长,有些人可能会说很好,但我认为有些部分可以更好。有时候我会迷失在其中。 - AlexRebula

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接