0

数日前から Twitter API と格闘していますが、認証されたユーザーのタイムラインにメッセージを投稿できません。Twitter 経由でユーザーをサインインさせ、サインイン プロセスから返されるアクセス トークンを保存する ASP.NET MVC 4 アプリケーションを用意しました。その部分はうまく機能します。認証されたユーザーの Twitter アカウント内で、読み取りと書き込みのアクセス許可を持つアプリケーションを確認できます。

次に、そのアクセス トークンを、Twitter アプリケーションに関連付けられたコンシューマー キー、コンシューマー シークレット、および oauth トークン シークレットと共に使用して、ユーザーのタイムラインに投稿します。毎回 401 無許可エラーが発生します。1.1 API と 1 API を使用してみましたが、結果は同じでした。

コードのほとんどは、Gary Short の記事 ( http://garyshortblog.wordpress.com/2011/02/11/a-twitter-oauth-example-in-c/ ) からのものです。

これが私がこれまでに得たものです。誰かが私が見逃しているものについての手がかりを見つけることができれば、私は最も感謝しています.

    public async Task<bool> Push(TwitterMessage twitterMessage)
    {
        const string updateApi = "http://api.twitter.com/1/statuses/update.json";
        const string oauthConsumerKey = "<consumerKey>";
        const string consumerSecret = "<consumerSecret>";
        const string oauthSignatureMethod = "HMAC-SHA1";
        const string oauthTokenSecret = "<tokenSecret>";
        var signingKey = string.Format("{0}&{1}", consumerSecret.Escaped(), oauthTokenSecret.Escaped());

        var postBody = "status=" + Uri.EscapeDataString(twitterMessage.MessageContent);
        var oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
        var oauthToken = "<authenticatedUserToken>";
        var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

        var message = string.Format("POST {0}?{1} HTTP/1.1", updateApi, postBody.Escaped());
        var hasher = new HMACSHA1(new ASCIIEncoding().GetBytes(signingKey));
        var signatureString = Convert.ToBase64String(hasher.ComputeHash(new ASCIIEncoding().GetBytes(message)));

        ServicePointManager.Expect100Continue = false;

        var request = (HttpWebRequest)WebRequest.Create(updateApi);
        request.KeepAlive = false;

        var authorisationBuilder = new StringBuilder();
        authorisationBuilder.Append("OAuth ");
        authorisationBuilder.AppendFormat("oauth_consumer_key=\"{0}\",", oauthConsumerKey.Escaped());
        authorisationBuilder.AppendFormat("oauth_signature_method=\"{0}\",", oauthSignatureMethod.Escaped());
        authorisationBuilder.AppendFormat("oauth_timestamp=\"{0}\",", oauthTimestamp.Escaped());
        authorisationBuilder.AppendFormat("oauth_nonce=\"{0}\",", oauthNonce.Escaped());
        authorisationBuilder.AppendFormat("oauth_token=\"{0}\",", oauthToken.Escaped());
        authorisationBuilder.AppendFormat("oauth_signature=\"{0}\"", signatureString.Escaped());
        var authorisation = authorisationBuilder.ToString();
        request.Headers.Add("Authorization", authorisation);

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        using (var stream = await request.GetRequestStreamAsync())
        {
            var bodyBytes = new ASCIIEncoding().GetBytes(postBody);
            stream.Write(bodyBytes, 0, bodyBytes.Length);
        }

        //Allow us a reasonable timeout in case Twitter's busy
        request.Timeout = 3 * 60 * 1000;

        try
        {
            var response = await request.GetResponseAsync() as HttpWebResponse;
            return true;
        }
        catch (WebException)
        {
            return false;
        } 
    }

    public static string Escaped(this string input)
    {
        return Uri.EscapeDataString(input);
    }

更新このSO 投稿を見ると、私が行っていた承認に DotNetOpenAuth Twitter クライアントを使用できないようです。承認を実行する代わりに、Twitter コンシューマー クラスを拡張することをお勧めします。これにより、ユーザーのトークン シークレットを取得できるようになります (私のパズルの欠けているピースだと思います)。これが機能するようになったら、別の更新を投稿します。

4

2 に答える 2

0

したがって、問題は現在の DotNetOpenAuth の問題です。Twitter 認証の場合、DotNetOpenAuth クライアントは完全な認証フロー (ユーザーのタイムラインへの投稿に必要) を許可しません。最初のハンドシェイクからアクセス トークンのみが取得され、アクセス トークン シークレットは取得されません。サインインしている Twitter ユーザーではなく、自分の Twitter アプリに関連付けられたアクセス トークン シークレットを使用していたため、認証は毎回失敗していました。

更新: 最終的に、Daniel Crenna のTweetsharpライブラリを使用することにしました。これにより、独自の API ラッパーを作成するよりもコードが少し簡単になります。

public async Task<bool> Push(TwitterAccount account)
{
    var twitterService = new TwitterService(consumerKey, consumerSecret);
    twitterService.AuthenticateWith(account.AccessToken, account.AccessTokenSecret);
    var options = new SendTweetOptions {Status = string.Format("{0} {1}", account.Message.MessageContent, account.Message.ShortLink)};
    var status = twitterService.SendTweet(options);
    return status != null;
}
于 2012-12-05T17:03:59.440 に答える