oauth2认证
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Configuration; using System.Text; using System.Web; using System.Net; using System.IO; namespace Twitter { class Auth { const string REQUEST_TOKEN_URL = "https://twitter.com/oauth/request_token"; const string ACCESS_TOKEN_URL = "https://twitter.com/oauth/access_token"; const string AUTHORIZE_URL = "https://twitter.com/oauth/authorize"; private Random random = new Random(); public string ConsumerKey { get; private set; } public string ConsumerSecret { get; private set; } public string RequestToken { get; private set; } public string RequestTokenSecret { get; private set; } public string AccessToken { get; private set; } public string AccessTokenSecret { get; private set; } public string UserId { get; private set; } public string ScreenName { get; private set; } public Auth(string consumerKey, string consumerSecret) { ServicePointManager.Expect100Continue = false; ConsumerKey = consumerKey; ConsumerSecret = consumerSecret; } public Auth(string consumerKey, string consumerSecret, string accessToken, string accessTokenSecret, string userId, string screenName) { ServicePointManager.Expect100Continue = false; ConsumerKey = consumerKey; ConsumerSecret = consumerSecret; AccessToken = accessToken; AccessTokenSecret = accessTokenSecret; UserId = userId; ScreenName = screenName; } public void GetRequestToken() { SortedDictionary<string, string> parameters = GenerateParameters(""); string signature = GenerateSignature("", "GET", REQUEST_TOKEN_URL, parameters); parameters.Add("oauth_signature", UrlEncode(signature)); string response = HttpGet(REQUEST_TOKEN_URL, parameters); Dictionary<string, string> dic = ParseResponse(response); RequestToken = dic["oauth_token"]; RequestTokenSecret = dic["oauth_token_secret"]; } public string GetAuthorizeUrl() { return AUTHORIZE_URL + "?oauth_token=" + RequestToken; } public void GetAccessToken(string pin) { SortedDictionary<string, string> parameters = GenerateParameters(RequestToken); parameters.Add("oauth_verifier", pin); string signature = GenerateSignature(RequestTokenSecret, "GET", ACCESS_TOKEN_URL, parameters); parameters.Add("oauth_signature", UrlEncode(signature)); string response = HttpGet(ACCESS_TOKEN_URL, parameters); Dictionary<string, string> dic = ParseResponse(response); AccessToken = dic["oauth_token"]; AccessTokenSecret = dic["oauth_token_secret"]; UserId = dic["user_id"]; ScreenName = dic["screen_name"]; } public string Get(string url, IDictionary<string, string> parameters) { SortedDictionary<string, string> parameters2 = GenerateParameters(AccessToken); foreach (var p in parameters) parameters2.Add(p.Key, p.Value); string signature = GenerateSignature(AccessTokenSecret, "GET", url, parameters2); parameters2.Add("oauth_signature", UrlEncode(signature)); return HttpGet(url, parameters2); } public string Post(string url, IDictionary<string, string> parameters) { SortedDictionary<string, string> parameters2 = GenerateParameters(AccessToken); foreach (var p in parameters) parameters2.Add(p.Key, p.Value); string signature = GenerateSignature(AccessTokenSecret, "POST", url, parameters2); parameters2.Add("oauth_signature", UrlEncode(signature)); return HttpPost(url, parameters2); } private string HttpGet(string url, IDictionary<string, string> parameters) { WebRequest req = WebRequest.Create(url + '?' + JoinParameters(parameters)); WebResponse res = req.GetResponse(); Stream stream = res.GetResponseStream(); StreamReader reader = new StreamReader(stream); string result = reader.ReadToEnd(); reader.Close(); stream.Close(); return result; } string HttpPost(string url, IDictionary<string, string> parameters) { byte[] data = Encoding.ASCII.GetBytes(JoinParameters(parameters)); WebRequest req = WebRequest.Create(url); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(data, 0, data.Length); reqStream.Close(); WebResponse res = req.GetResponse(); Stream resStream = res.GetResponseStream(); StreamReader reader = new StreamReader(resStream, Encoding.UTF8); string result = reader.ReadToEnd(); reader.Close(); resStream.Close(); return result; } private Dictionary<string, string> ParseResponse(string response) { Dictionary<string, string> result = new Dictionary<string, string>(); foreach (string s in response.Split('&')) { int index = s.IndexOf('='); if (index == -1) result.Add(s, ""); else result.Add(s.Substring(0, index), s.Substring(index + 1)); } return result; } private string JoinParameters(IDictionary<string, string> parameters) { StringBuilder result = new StringBuilder(); bool first = true; foreach (var parameter in parameters) { if (first) first = false; else result.Append('&'); result.Append(parameter.Key); result.Append('='); result.Append(parameter.Value); } return result.ToString(); } private string GenerateSignature(string tokenSecret, string httpMethod, string url, SortedDictionary<string, string> parameters) { string signatureBase = GenerateSignatureBase(httpMethod, url, parameters); HMACSHA1 hmacsha1 = new HMACSHA1(); hmacsha1.Key = Encoding.ASCII.GetBytes(UrlEncode(ConsumerSecret) + '&' + UrlEncode(tokenSecret)); byte[] data = System.Text.Encoding.ASCII.GetBytes(signatureBase); byte[] hash = hmacsha1.ComputeHash(data); return Convert.ToBase64String(hash); } private string GenerateSignatureBase(string httpMethod, string url, SortedDictionary<string, string> parameters) { StringBuilder result = new StringBuilder(); result.Append(httpMethod); result.Append('&'); result.Append(UrlEncode(url)); result.Append('&'); result.Append(UrlEncode(JoinParameters(parameters))); return result.ToString(); } private SortedDictionary<string, string> GenerateParameters(string token) { SortedDictionary<string, string> result = new SortedDictionary<string, string>(); result.Add("oauth_consumer_key", ConsumerKey); result.Add("oauth_signature_method", "HMAC-SHA1"); result.Add("oauth_timestamp", GenerateTimestamp()); result.Add("oauth_nonce", GenerateNonce()); result.Add("oauth_version", "1.0"); if (!string.IsNullOrEmpty(token)) result.Add("oauth_token", token); return result; } public string UrlEncode(string value) { string unreserved = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; StringBuilder result = new StringBuilder(); byte[] data = Encoding.UTF8.GetBytes(value); foreach (byte b in data) { if (b < 0x80 && unreserved.IndexOf((char)b) != -1) result.Append((char)b); else result.Append('%' + String.Format("{0:X2}", (int)b)); } return result.ToString(); } private string GenerateNonce() { string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; StringBuilder result = new StringBuilder(8); for (int i = 0; i < 8; ++i) result.Append(letters[random.Next(letters.Length)]); return result.ToString(); } private string GenerateTimestamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } } class Program { const string CONSUMER_KEY = "hogehogehogehogehoge"; const string CONSUMER_SECRET = "fugafugafugafugafugafugafugafuga"; static void Main(string[] args) { Auth auth; var settings = Twitter.Properties.Settings.Default; if (string.IsNullOrEmpty((string)settings["AccessToken"])) { auth = new Auth(CONSUMER_KEY, CONSUMER_SECRET); // リクエストトークンを取得する auth.GetRequestToken(); // ユーザーにRequestTokenを認証してもらう Console.WriteLine("次のURLにアクセスして暗証番号を取得してください:"); Console.WriteLine(auth.GetAuthorizeUrl()); Console.Write("暗証番号:"); string pin = Console.ReadLine().Trim(); // アクセストークンを取得する auth.GetAccessToken(pin); // 結果を表示する Console.WriteLine("AccessToken: " + auth.AccessToken); Console.WriteLine("AccessTokenSecret: " + auth.AccessTokenSecret); Console.WriteLine("UserId: " + auth.UserId); Console.WriteLine("ScreenName: " + auth.ScreenName); // アクセストークンを設定ファイルに保存する settings["AccessToken"] = auth.AccessToken; settings["AccessTokenSecret"] = auth.AccessTokenSecret; settings["UserId"] = auth.UserId; settings["ScreenName"] = auth.ScreenName; settings.Save(); } else { // 設定ファイルから読み込む auth = new Auth(CONSUMER_KEY, CONSUMER_SECRET, (string)settings["AccessToken"], (string)settings["AccessTokenSecret"], (string)settings["UserId"], (string)settings["ScreenName"]); } // ↓ここらへんは後でちゃんとwrapしたい // タイムラインから3件取得してみる Dictionary<string, string> parameters = new Dictionary<string, string>(); parameters.Add("count", "3"); Console.WriteLine(auth.Get("http://twitter.com/statuses/home_timeline.xml", parameters)); // ポストしてみる Console.WriteLine("いまどうしてる?"); string status = Console.ReadLine(); parameters.Clear(); parameters.Add("status", auth.UrlEncode(status)); Console.WriteLine(auth.Post("http://twitter.com/statuses/update.xml", parameters)); } } }
虽功未成,亦未敢藏私,众侠诸神通尽录于此,竟成一笈,名葵花宝典,以飨后世。
邮箱:steven9801@163.com
QQ: 48039387
邮箱:steven9801@163.com
QQ: 48039387