如何通过OAuth将Twitter消息发布到经过身份验证的用户的时间线



我已经与Twitter API进行了几天的斗争,但我无法将消息发布到经过身份验证的用户的时间线。我有一个ASP.NET MVC 4应用程序,它可以通过Twitter让用户登录,并保存登录过程中返回的访问令牌。那部分很好用。我可以在经过身份验证的用户的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消费者类来执行授权,这将允许我检索用户的令牌秘密(我认为这是我拼图中缺失的部分)。当我开始工作时,会发布另一个更新。

检查此代码并简单地链接/文章:

protected void btnTweet_Click(object sender, EventArgs e)
{
string oauthAccessToken = Session["twtoken"].ToString();
string oauthAccessTokenSecret = Session["twsecret"].ToString();
OAuthHelper oauthhelper = new OAuthHelper();
oauthhelper.TweetOnBehalfOf(oauthAccessToken, oauthAccessTokenSecret, txtTweet.Text);
if (string.IsNullOrEmpty(oauthhelper.oauth_error))
Response.Write("Twit Posted Successfully");
else
Response.Write(oauthhelper.oauth_error);
}

阅读更多如何获得访问令牌和密钥并下载OAuthHelper和OAuthUtility类下面是链接-

如何使用oauth身份验证代表asp.net用户发布推文

在asp.net中使用oauth身份验证登录twitter,并获取访问令牌、屏幕名称和用户ID

因此,问题是DotNetOpenAuth目前的问题。对于Twitter身份验证,DotNetOpenAuth客户端不允许完全授权流(发布到用户的时间线所需)。仅从初始握手中检索访问令牌,而不检索访问令牌机密。我使用的是与我的推特应用程序相关的访问令牌机密,而不是登录的推特用户,所以每次授权都会失败。

更新:我终于使用了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;
}

相关内容

最新更新