Created
November 26, 2011 11:25
-
-
Save mimura1133/1395485 to your computer and use it in GitHub Desktop.
Twitter OAuth 1.0 Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Net; | |
using System.Security.Cryptography; | |
using System.Text; | |
using System.Web; | |
/* | |
* この辺を参考に: | |
* | |
* http://oauth.net/core/1.0 | |
* http://hueniverse.com/oauth/guide/authentication/ | |
* https://dev.twitter.com/docs/auth/authorizing-request | |
*/ | |
namespace Direct_Commit_Twitter | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// | |
// 使うパラメータは次のようなもの。 | |
// | |
// OAuth Consumer Key : Consumer Key そのまま。 | |
// OAuth Token : Access Token そのまま。 (今回はこれも取得。) | |
// OAuth Nonce : ランダム文字列を与える。 (毎回変更する。) | |
// OAuth Signature : OAuth Signature 以外の値で HMAC-SHA1 をとった値。 | |
// OAuth Signature Method : Twitter は HMAC-SHA1 指定っぽいので HMAC-SHA1. | |
// OAuth Time Stamp : UNIX 時間 (1970-01-01 UTC からの秒数) を与える。 | |
// : (今回は GetUNIXTime() メソッドで取得します。) | |
// OAuth Version : 今回は 1.0 を使うので、1.0. | |
// | |
string consumer_key = ""; | |
string consumer_secret = ""; | |
string access_token = ""; | |
string access_secret = ""; | |
string tweet_text = "ゲソーゲソー"; | |
/************************ 以下、黙々と処理 ********************/ | |
string[] verify_token; | |
if (access_token == "" || access_secret == "") | |
{ | |
#region 01. Request Token を取得しなイカ? | |
{ | |
Console.WriteLine("01 - Token を取得しなイカ?"); | |
Console.WriteLine("-------------------------------------------------"); | |
Random rand = new Random(); | |
byte[] nonce_b = new byte[64]; | |
rand.NextBytes(nonce_b); | |
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString(); | |
long unixtime = GetUNIXTime(); | |
// | |
// OAuth Signature 生成のために、それ以外で仮のリクエスト文字列を作成する。 | |
// この際、各パラメータは ABC 順にソートされている必要がある。 | |
// | |
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/request_token"); | |
signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, null, null, null)); | |
// | |
// ちゃんとしたリクエスト文字列を作る。 | |
// | |
string signature = GetSignature(consumer_secret, null, signature_request); | |
string param = MakeParamString(consumer_key, nonce, signature, unixtime, null, null, null); | |
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, null, null, null); | |
return; | |
// | |
// 問い合わせ。 | |
// | |
Console.WriteLine("* Access : https://api.twitter.com/oauth/request_token?" + param); | |
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/request_token?" + param); | |
hwr.Method = "POST"; | |
WebResponse ret = hwr.GetResponse(); | |
verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&'); | |
ret.Close(); | |
Console.WriteLine(); | |
Console.WriteLine("Response : "); | |
foreach (string s in verify_token) | |
Console.WriteLine("> " + s); | |
} | |
#endregion | |
#region 02. Access Token を取得しなイカ? | |
{ | |
Console.WriteLine(); | |
Console.WriteLine("02 - Access Token を取得しなイカ?"); | |
Console.WriteLine("-------------------------------------------------"); | |
string request_token = ""; | |
string request_secret = ""; | |
// | |
// ブラウザ開いて認証。 | |
// | |
foreach (string s in verify_token) | |
{ | |
int p = s.IndexOf("oauth_token="); | |
if (p != -1) | |
{ | |
request_token = s.Substring(p + "oauth_token=".Length); | |
break; | |
} | |
} | |
Console.WriteLine("- OAuth Token : " + request_token); | |
Console.WriteLine("* Browser Open : https://twitter.com/oauth/authorize?oauth_token=" + request_token); | |
Process.Start("https://twitter.com/oauth/authorize?oauth_token=" + request_token); | |
// | |
// PIN を入力させる。 | |
// | |
Console.Write("\nINPUT PIN : "); | |
string pin = Console.ReadLine(); | |
foreach (string s in verify_token) | |
{ | |
int p = s.IndexOf("oauth_token_secret="); | |
if (p != -1) | |
{ | |
request_secret = s.Substring(p + "oauth_token_secret=".Length); | |
break; | |
} | |
} | |
// | |
// 以下 Twitter ともくもく通信。 | |
// | |
Random rand = new Random(); | |
byte[] nonce_b = new byte[64]; | |
rand.NextBytes(nonce_b); | |
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString(); | |
long unixtime = GetUNIXTime(); | |
// | |
// Signature 生成のための一時的なリクエスト文字列を作成。 | |
// | |
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/access_token"); | |
signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, request_token, pin, null)); | |
string signature = GetSignature(consumer_secret, request_secret, signature_request); | |
string param = MakeParamString(consumer_key, nonce, signature, unixtime, request_token, pin, null); | |
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, request_token, request_secret, pin); | |
// | |
// 問い合わせ。 | |
// | |
Console.WriteLine("* Access : https://api.twitter.com/oauth/access_token?" + param); | |
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/access_token?" + param); | |
hwr.Method = "POST"; | |
hwr.Headers.Add("Authorization", "OAuth"); | |
WebResponse ret = hwr.GetResponse(); | |
verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&'); | |
ret.Close(); | |
Console.WriteLine(); | |
Console.WriteLine("Response : "); | |
foreach (string s in verify_token) | |
{ | |
if (s.IndexOf("oauth_token=") != -1) | |
access_token = s.Substring(s.IndexOf("=") + 1); | |
if (s.IndexOf("oauth_token_secret=") != -1) | |
access_secret = s.Substring(s.IndexOf("=") + 1); | |
Console.WriteLine("> " + s); | |
} | |
} | |
#endregion | |
} | |
#region 03. つぶやかなイカ? | |
{ | |
Console.WriteLine(); | |
Console.WriteLine("03 - つぶやかなイカ?"); | |
Console.WriteLine("-------------------------------------------------"); | |
Random rand = new Random(); | |
byte[] nonce_b = new byte[64]; | |
rand.NextBytes(nonce_b); | |
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString(); | |
long unixtime = GetUNIXTime(); | |
string tweet_data = UrlEncode(tweet_text); | |
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/1/statuses/update.xml"); | |
signature_request += "&include_entities%3Dtrue%26" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, access_token, null, tweet_data)); | |
string signature = GetSignature(consumer_secret, access_secret, signature_request); | |
string header_param = "OAuth oauth_consumer_key=\"" + UrlEncode(consumer_key) + "\",oauth_signature_method=\"HMAC-SHA1\"," + | |
"oauth_timestamp=\"" + unixtime + "\",oauth_nonce=\"" + UrlEncode(nonce) + "\"," + | |
"oauth_version=\"1.0\",oauth_token=\"" + UrlEncode(access_token) + "\"," + | |
"oauth_signature=\"" + UrlEncode(signature) + "\","; | |
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, access_token, access_secret, null); | |
Console.WriteLine("* Access : https://api.twitter.com/1/statuses/update.xml"); | |
Console.WriteLine("* Tweet at : " + tweet_text); | |
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/1/statuses/update.xml"); | |
hwr.Method = "POST"; | |
hwr.ServicePoint.Expect100Continue = false; | |
hwr.Headers.Add(HttpRequestHeader.Authorization, header_param); | |
hwr.ContentType = "application/x-www-form-urlencoded"; | |
var s = new StreamWriter(hwr.GetRequestStream()); | |
s.Write("status=" + tweet_data + "&include_entities=true"); | |
s.Close(); | |
WebResponse ret = hwr.GetResponse(); | |
Console.WriteLine(); | |
Console.WriteLine("Response:"); | |
Console.WriteLine("> "+(new StreamReader(ret.GetResponseStream()).ReadToEnd())); | |
} | |
#endregion | |
} | |
// UNIX 時間を返す。 | |
static long GetUNIXTime() | |
{ | |
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; | |
} | |
// URLエンコード (どうやらエスケープ文字は大文字にしないといけないらしい。) | |
static string UrlEncode(string str) | |
{ | |
string s = HttpUtility.UrlEncode(str); | |
return _UrlEncodeUpper(s); | |
} | |
static string _UrlEncodeUpper(string str) | |
{ | |
int p = str.IndexOf("%"); | |
if (p != -1) | |
{ | |
str = str.Substring(0, p) + str.Substring(p, 3).ToUpper() + _UrlEncodeUpper(str.Substring(p + 3)); | |
} | |
return str; | |
} | |
// パラメータ文字列を生成 | |
static string MakeParamString(string oauth_consumer_key, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_verifier, string status) | |
{ | |
string param = "oauth_consumer_key=" + oauth_consumer_key + "&oauth_nonce=" + oauth_nonce; | |
if (oauth_signature != null) | |
param += "&oauth_signature=" + oauth_signature; | |
param += "&oauth_signature_method=HMAC-SHA1" + "&oauth_timestamp=" + oauth_timestamp; | |
if (oauth_token != null) | |
param += "&oauth_token=" + oauth_token; | |
if (oauth_verifier != null) | |
param += "&oauth_verifier=" + oauth_verifier; | |
param += "&oauth_version=1.0"; | |
if (status != null) | |
param += "&status=" + status; | |
return param; | |
} | |
// Consumer Secret をKey とした、リクエスト文字列のハッシュを求める。 | |
static string GetSignature(string consumer_secret, string access_token_secret, string param) | |
{ | |
HMACSHA1 hmacsha1 = new HMACSHA1(); | |
hmacsha1.Key = Encoding.ASCII.GetBytes(consumer_secret + "&" + access_token_secret); | |
byte[] hash = hmacsha1.ComputeHash(Encoding.ASCII.GetBytes(param)); | |
return Convert.ToBase64String(hash); | |
} | |
// よくやる出力をまとめてみる。 | |
static void DebugParamOut(string oauth_consumer_key, string oauth_consumer_secret, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_token_secret, string oauth_verifier) | |
{ | |
Console.WriteLine("- OAuth Consumer Key = " + oauth_consumer_key); | |
Console.WriteLine("- OAuth Consumer Secret = " + oauth_consumer_secret); | |
Console.WriteLine("- OAuth Nonce = " + oauth_nonce); | |
if (oauth_signature != null) | |
Console.WriteLine("- OAuth Signature = " + oauth_signature); | |
Console.WriteLine("- OAuth Time Stamp = " + oauth_timestamp); | |
if (oauth_token != null) | |
Console.WriteLine("- OAuth Access Token = " + oauth_token); | |
if (oauth_token_secret != null) | |
Console.WriteLine("- OAuth Access Token Secret = " + oauth_token_secret); | |
if (oauth_verifier != null) | |
Console.WriteLine("- OAuth Verifier = " + oauth_verifier); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment