OAuth認証を試す
はてながOAuth認証に対応したというのでちょっと試してみた。
自分用のまとめもかねて書いてみる。
準備
Hatena Developer Center
ここらを手がかりにして、まずは「アプリケーション登録」をしておく。
OAuth Community
コミュニティにてJava版のライブラリ(ソースコード)が公開されてるのでこれを利用してみた。
twitter4jみたくtwitterに特化したのはブログとかみつかるんだけどね。
ソースサンプル
初期化
基本OAuth認証で使用するクラスは次の3つ。
- OAuthServiceProvider
- OAuthConsumer
- OAuthAccessor
private static final String REQUEST_TOKEN_URL = "https://www.hatena.com/oauth/initiate"; private static final String AUTHORIZE_URL = "https://www.hatena.ne.jp/touch/oauth/authorize"; private static final String ACCESS_TOKEN_URL = "https://www.hatena.com/oauth/token"; private static final String CALLBACK_URL = "oob"; private static final String CONSUMER_KEY = "取得したキー"; private static final String CONSUMER_SECRET_KEY = "取得したシークレットキー"; private OAuthServiceProvider provider; private OAuthConsumer consumer; private OAuthAccessor accessor; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); provider = new OAuthServiceProvider(REQUEST_TOKEN_URL, AUTHORIZE_URL, ACCESS_TOKEN_URL); consumer = new OAuthConsumer(CALLBACK_URL, CONSUMER_KEY, CONSUMER_SECRET_KEY, provider); accessor = new OAuthAccessor(consumer);
Providerにリクエストトークン、認証サイト、アクセストークンを取得するためのURLを設定して初期化。
アドレスはHatena Developer Centerに書いてあるし、個人のアプリ登録確認ページでもわかる。
ConsumerにはコールバックURL、アプリ登録で発行されたキーと秘密キーを設定。
今回はAndroidアプリで試してるのでコールバックには「oob」を指定。(何の略か不明)
これらのProviderとCunsumer情報を持ったAccessorを作成して準備は完了。
リクエストトークンの取得
ユーザの任意でアプリケーションの利用を許可してもらうための準備としてまずリクエストトークンを取得する。
このとき、はてな固有でscopeも指定する必要あり。
OAuthClient client = new OAuthClient(new HttpClient3()); Map<String, String> parameter = new HashMap<String, String>(); parameter.put(OAuth.OAUTH_CALLBACK, CALLBACK_URL); parameter.put("scope", "read_public,write_public,read_private,write_private"); OAuthMessage message = client.getRequestTokenResponse(accessor, "POST", parameter.entrySet()); String oauthToken = message .getParameter("oauth_token"); String oauthTokenSecret = message .getParameter("oauth_token_secret");
通信が成功すればOAuthMessageのパラメータとして取得可能。
取得ができたらブラウザを起動し認証ページに遷移させる。
このとき、リクエストパラメータとしてリクエストトークンを付与する。
String redirectUri = OAuth.addParameters(AUTHORIZE_URL, "oauth_token", oauthToken); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(redirectUri)); startActivity(intent);
Verifierの入力〜アクセストークンの取得
認証ページでユーザが許可すると、画面にVerifierキーが表示されるので、これをアプリに入力してもらう。
そのキーを持ってアクセストークンの取得をする。
Map<String, String> parameter = new HashMap<String, String>(); parameter.put(OAuth.OAUTH_VERIFIER, verifierText.getText().toString()); OAuthMessage message = client.getAccessToken(accessor, "POST", parameter.entrySet());
このときAccessorはリクエストトークンを取得した時のを使い回している。
Clientはインスタンスを作り直しても可。
はてな側から正常(HttpStatus200)が返ってくればOAuthMessageのパラメータにアクセストークンが含まれている。
これ(アクセストークン)さえあれば次回以降、トークンを使用してアクセスが可能になる。
Map<String, Object> keys = new HashMap<String, Object>(); keys.put("UserID", result.getParameter("url_name")); keys.put("UserName", result.getParameter("display_name")); keys.put("AccessToken", result.getParameter("oauth_token")); keys.put("AccessTokenSecret", result.getParameter("oauth_token_secret")); keys.put("RequestToken", accessor.requestToken);
OAuthAPIの利用
アクセストークンを取得したらあとはOAuthAPIを利用するだけ。
はてなダイアリーのAPIの場合、こんな感じになる。
// 2回目以降などアクセストークンを再利用する場合 OAuthAccessor newAccessor = new OAuthAccessor(consumer); newAccessor.accessToken = (String) keys.get("AccessToken"); newAccessor.tokenSecret = (String) keys.get("AccessTokenSecret"); newAccessor.requestToken = (String) keys.get("RequestToken"); Map<String, String> userAgent = new HashMap<String, String>(); userAgent.put("User-Agent", "Android"); OAuthMessage request = newAccessor.newRequestMessage("GET", "http://d.hatena.ne.jp/gsh-kz/atom/blog", null); request.getHeaders().addAll(userAgent.entrySet()); OAuthResponseMessage message = client.access(request, ParameterStyle.AUTHORIZATION_HEADER);
何が罠って、Hatena Developer CenterのどこにもUserAgentが必要とか書いてないこと。
これがわからなくて4時間以上はまってたorz
ちなみにkeysは設定ファイルに保存してたのをMap形式で取得してるため。
ResponseMessageにはてな側から返却されたストリームが参照できるんで、UTF-8エンコードして読み取れば一覧がみれる。
わかればどってことない簡単なAPIを使用するだけなんだけど。
ライブラリさまさまだわ。