かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Twitterにログインするまでの道のり(OAuthなんて嫌いだ!)

いい時代になりました。 id:neueccさんの、AsyncOAuthを使えば簡単にTwitterの認証を突破できる…。が!!Twitter初心者なんで使い方がよくわからなかったのでメモっておきます。

アプリの登録

  • Twitterの開発者向けサイトでログインします。
  • 右上の自分のアイコンからMy applicationsを選びます。
  • 各種項目を埋めていきます
    • Name: 名前
    • Description: 概要
    • Website: まぁアプリのページとか
    • Callback URL: 自分のドメインのサイトのURLでも入れておいて。適当でも動くっぽいけど…。
    • 最後の規約を読んで、OKならチェックを入れて Create your Twitter application

Callback URLは、後でアプリで使うので控えておきましょう。

キーの取得

  • アプリの登録が出来たらアプリのページにいくので、API Keysのタブを選びます。
  • API key(俗にConsumerKey)とAPI secret(俗にConsumerKeySecret)を控えておきます

アプリで認証を通す

Windowsストアアプリを新規作成したら迷わず、NuGetでAsyncOAuthを入れます。そして、App.xaml.csのOnLaunchedメソッドの先頭に以下のコードを書きます。

// Windows Store App(めんどうくせえええええ)
AsyncOAuth.OAuthUtility.ComputeHash = (key, buffer) =>
{
    var crypt = Windows.Security.Cryptography.Core.MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
    var keyBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(key);
    var cryptKey = crypt.CreateKey(keyBuffer);

    var dataBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(buffer);
    var signBuffer = Windows.Security.Cryptography.Core.CryptographicEngine.Sign(cryptKey, dataBuffer);

    byte[] value;
    Windows.Security.Cryptography.CryptographicBuffer.CopyToByteArray(signBuffer, out value);
    return value;
};

コメントの気持ち大事なので忘れないようにコピペしましょう。

後のコードはこんな感じ。認証してTwitterAPIに触れるHttpClientがとれるまでのコードをべたっと書きました。

// コピペしたキー(もう消してるから使えないけど)
var consumerKey = "2UHG3NsP6dKvAOHVP5xOvsizj";
var consumerKeySecret = "y94OwzrXRfhYKRGiCyGhlGWcbqMI64mcck8ptXVtZB8QnR9KVm";

// コールバックURL(アプリ登録したときに入力したやつ)
var callbackUrl = "http://okazuki.hogehoge.fuga"; // ちゃんとしたURLを指定しましょう

// 認証に使う一連のAPIのURL
var requestTokenUrl =  "https://api.twitter.com/oauth/request_token";
var authorizeUrl = "https://api.twitter.com/oauth/authorize";
var accessTokenUrl = "https://api.twitter.com/oauth/access_token";

// AsyncOAuthにお願いしてパラメータを作ってもらう
var param = OAuthUtility.BuildBasicParameters(
    consumerKey,
    consumerKeySecret,
    requestTokenUrl,
    HttpMethod.Post);

// 認証のめんどくさいことをしてくれる人を作る
var authrizer = new OAuthAuthorizer(consumerKey, consumerKeySecret);

// リクエストトークンというものを貰う
var tokenResponse = await authrizer.GetRequestToken(requestTokenUrl);
var requestToken = tokenResponse.Token;

// 認証画面のURLを貰う
var pinRequestUrl = authrizer.BuildAuthorizeUrl(authorizeUrl, requestToken);

// WebAuthenticationBrokerを使って認証画面を出す
var result = await WebAuthenticationBroker.AuthenticateAsync(
    WebAuthenticationOptions.None,
    new Uri(pinRequestUrl),
    new Uri(callbackUrl));

// 結果からHttpのパラメータを抜き取る
var query = result.ResponseData.Split('?')[1];
var parameters = new Dictionary<string, string>();
foreach (var token in query.Split('&'))
{
    var keyValue = token.Split('=');
    parameters[keyValue[0]] = WebUtility.UrlDecode(keyValue[1]);
}

// アクセストークンを取得する
var accessToken = await authrizer.GetAccessToken(accessTokenUrl, requestToken, parameters["oauth_verifier"]);

// APIにアクセスするためのHttpClientを取得する
var client = OAuthUtility.CreateOAuthClient(
    consumerKey,
    consumerKeySecret,
    accessToken.Token);

この後に例えばこんなコードを書くとHomeタイムラインがとってこれます。

var res = await client.GetAsync("https://api.twitter.com/1.1/statuses/home_timeline.json");
Debug.WriteLine(await res.Content.ReadAsStringAsync());