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を使用するだけなんだけど。
ライブラリさまさまだわ。