我想提供一个功能来登录 Twitter 并从 Windows 8.1 通用应用程序发布推文。请不要建议我去第三方图书馆。我只想做两件事。我的努力如下。我怀疑我的身份验证是错误的。我收到System.Net.WebException => 远程服务器返回错误:(401)未经授权。我的代码有什么问题,有人知道吗?
public const string TwitterClientID = "XXXXXXXXXXXL3nZGhtKURASXg";
public const string TwitterClientSecret = "5HBuM1FVXXXXXXXXXXXXXXqaSm1awtNSes";
public const string TwitterCallbackUrl = "http://f.com";
public const string TweetFromAPI = "Tweeting from API";
String Oauth_token = null;
String Oauth_token_secret = null;
private async Task TwitterLogin()
{
TimeSpan SinceEpoch = (DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
Random Rand = new Random();
String TwitterUrl = "https://api.twitter.com/oauth/request_token";
Int32 Nonce = Rand.Next(1000000000);
String SigBaseStringParams = "oauth_callback=" + Uri.EscapeDataString(TwitterCallbackUrl);
SigBaseStringParams += "&" + "oauth_consumer_key=" + TwitterClientID;
SigBaseStringParams += "&" + "oauth_nonce=" + Nonce.ToString();
SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
SigBaseStringParams += "&" + "oauth_timestamp=" + Math.Round(SinceEpoch.TotalSeconds);
SigBaseStringParams += "&" + "oauth_version=1.0";
String SigBaseString = "POST&";
SigBaseString += Uri.EscapeDataString(TwitterUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);
IBuffer KeyMaterial = CryptographicBuffer.ConvertStringToBinary(TwitterClientSecret + "&", BinaryStringEncoding.Utf8);
MacAlgorithmProvider HmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
CryptographicKey MacKey = HmacSha1Provider.CreateKey(KeyMaterial);
IBuffer DataToBeSigned = CryptographicBuffer.ConvertStringToBinary(SigBaseString, BinaryStringEncoding.Utf8);
IBuffer SignatureBuffer = CryptographicEngine.Sign(MacKey, DataToBeSigned);
String Signature = CryptographicBuffer.EncodeToBase64String(SignatureBuffer);
String DataToPost = "OAuth oauth_callback=\"" + Uri.EscapeDataString(TwitterCallbackUrl) + "\", oauth_consumer_key=\"" + TwitterClientID + "\", oauth_nonce=\"" + Nonce.ToString() + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + Math.Round(SinceEpoch.TotalSeconds) + "\", oauth_version=\"1.0\", oauth_signature=\"" + Uri.EscapeDataString(Signature) + "\"";
var m_PostResponse = await PostData(TwitterUrl, DataToPost, false);
if (m_PostResponse != null)
{
String[] keyValPairs = m_PostResponse.Split('&');
for (int i = 0; i < keyValPairs.Length; i++)
{
String[] splits = keyValPairs[i].Split('=');
switch (splits[0])
{
case "oauth_token":
Oauth_token = splits[1];
break;
case "oauth_token_secret":
Oauth_token_secret = splits[1];
break;
}
}
if (Oauth_token != null)
{
TwitterUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + Oauth_token;
System.Uri StartUri = new Uri(TwitterUrl);
System.Uri EndUri = new Uri(TwitterCallbackUrl);
WebAuthenticationResult WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
StartUri,
EndUri);
if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
{
var text = WebAuthenticationResult.ResponseData.Split(new char[] { '?' })[1];
var dict = text.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
.Select(part => part.Split('='))
.ToDictionary(split => split[0], split => split[1]);
//Oauth_token = dict["oauth_token"];
//Oauth_token_secret = dict["oauth_verifier"];
await PostTweet();
}
else if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
{
}
else
{
}
}
}
}
private async Task<String> PostData(String Url, String Data, bool flag)
{
string m_PostResponse = null;
try
{
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(Url);
Request.Method = "POST";
if (flag)
{
Request.ContentType = "application/x-www-form-urlencoded";
}
Request.Headers["Authorization"] = Data;
if (flag)
{
using (Stream stream = await Request.GetRequestStreamAsync())
{
var postBody = "status=" + Uri.EscapeDataString(TweetFromAPI);
byte[] content = System.Text.Encoding.UTF8.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
}
HttpWebResponse Response = (HttpWebResponse)await Request.GetResponseAsync();
StreamReader ResponseDataStream = new StreamReader(Response.GetResponseStream());
m_PostResponse = await ResponseDataStream.ReadToEndAsync();
}
catch (Exception)
{
throw;
}
return m_PostResponse;
}
public async Task PostTweet()
{
Random Rand = new Random();
Int32 Nonce = Rand.Next(1000000000);
string status = TweetFromAPI;
string postBody = "status=" + Uri.EscapeDataString(status);
string oauth_consumer_key = TwitterClientID;
string oauth_consumerSecret = TwitterClientSecret;
string oauth_signature_method = "HMAC-SHA1";
string oauth_version = "1.0";
string oauth_token = Oauth_token;
string oauth_token_secret = Oauth_token_secret;
string oauth_nonce = Nonce.ToString();
TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
string oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
SortedDictionary<string, string> basestringParameters = new SortedDictionary<string, string>();
basestringParameters.Add("status", Uri.EscapeDataString(status));
basestringParameters.Add("oauth_version", oauth_version);
basestringParameters.Add("oauth_consumer_key", oauth_consumer_key);
basestringParameters.Add("oauth_nonce", oauth_nonce);
basestringParameters.Add("oauth_signature_method", oauth_signature_method);
basestringParameters.Add("oauth_timestamp", oauth_timestamp);
basestringParameters.Add("oauth_token", oauth_token);
//Build the signature string
string baseString = String.Empty;
baseString += "POST" + "&";
baseString += Uri.EscapeDataString("https://api.twitter.com/1.1/statuses/update.json") + "&";
foreach (KeyValuePair<string, string> entry in basestringParameters)
{
baseString += Uri.EscapeDataString(entry.Key + "=" + entry.Value + "&");
}
baseString = baseString.Substring(0, baseString.Length - 3);
//Build the signing key
string signingKey = Uri.EscapeDataString(oauth_consumerSecret) +
"&" + Uri.EscapeDataString(oauth_token_secret);
IBuffer KeyMaterial = CryptographicBuffer.ConvertStringToBinary(TwitterClientSecret + "&", BinaryStringEncoding.Utf8);
MacAlgorithmProvider HmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
CryptographicKey MacKey = HmacSha1Provider.CreateKey(KeyMaterial);
IBuffer DataToBeSigned = CryptographicBuffer.ConvertStringToBinary(signingKey, BinaryStringEncoding.Utf8);
IBuffer SignatureBuffer = CryptographicEngine.Sign(MacKey, DataToBeSigned);
String signatureString = CryptographicBuffer.EncodeToBase64String(SignatureBuffer);
string authorizationHeaderParams = String.Empty;
authorizationHeaderParams += "OAuth ";
authorizationHeaderParams += "oauth_nonce=" + "\"" +
Nonce.ToString() + "\",";
authorizationHeaderParams += "oauth_signature_method=" +
"\"" + Uri.EscapeDataString(oauth_signature_method) + "\",";
authorizationHeaderParams += "oauth_timestamp=" + "\"" +
Uri.EscapeDataString(oauth_timestamp) + "\",";
authorizationHeaderParams += "oauth_consumer_key=" + "\"" +
Uri.EscapeDataString(oauth_consumer_key) + "\",";
authorizationHeaderParams += "oauth_token=" + "\"" +
Uri.EscapeDataString(oauth_token) + "\",";
authorizationHeaderParams += "oauth_signature=" + "\"" +
Uri.EscapeDataString(signatureString) + "\",";
authorizationHeaderParams += "oauth_version=" + "\"" +
Uri.EscapeDataString(oauth_version) + "\"";
var respo = await PostData("https://api.twitter.com/1.1/statuses/update.json", authorizationHeaderParams, true);
}