2010年8月17日火曜日

Twitter4j-2.1.xを使ったOAuth認証のコーディング例

【セルフPR】
・ねこぱβ(http://cat.picparks.com
・いぬぱβ(http://dog.picparks.com
も見てくれると嬉しいです。

---

Twitter4jは2.1系から2.2系で使い方が変わったので、2.2系をお使いになる場合は、こちらの記事をご覧ください。

Twitterクライアントを作るに当たって必要な認証方法として、
前のエントリで書いたように、よりセキュアな認証方法であるOAuth。

Twitter4jとSignpostの併用とか訳の分からないコーディングや、
返ってきたaccess_tokenをユーザーにメモらせたり、
JavaScriptで解析させたりするコーディング等、
クライアントアプリケーションだけで処理が閉じた、
まともなコーディング例が見つからずハマりまくったので、
僕のレベルで考えうるベストのコーディング例を紹介します。

説明が超ヘタクソなので、実際のソースを
TwitterLogin.java
TwitterSetting.java
に置いておきます。
ご自由にどうぞ。
※Dropboxにリンクしています。
ご覧になれない方がいらっしゃるようなので、
欲しい方はTwitter(@ky25_android)でメッセージください。

また、この実装を利用したアプリのソースを丸ごと公開しておりますので、
こちら
からダウンロードしてみてください。

■開発環境
・JDK 6
・Android SDK Tools, Revision 6
・Twitter4j-2.1.3

■前提
1.アプリケーション登録が完了している。(※)
※OAuthを使う場合、クライアントアプリであっても、
「ブラウザアプリケーション」として登録する。
2.Twitterに飛ぶためのボタン1つだけのActivity(以下、Activity1)と、
Twitterの認証画面を表示するActivity(以下、Activity2)の構成(※)。
※Activity2用に、WebViewを使ったレイアウトをあらかじめ作成しておく。
このレイアウトに設定したWebViewは、WebView01というIDにしています。

■注意点
1.CALLBACK URLには適当な文字列を設定しておく。
Twitterのアプリ登録で指定したCALLBACK URLとは別にしておいた方が混乱しない。
2.下記コードの中で「oauth_verifier」という概念が出てくるが、
これはaccess_tokenとaccess_token_secretを付与してもらうためのキー。

■コーディング例

●Activity1のコーディング例
1.下記コードを、Activity2を呼ぶために、
onCreateメソッド内のsetOnClickListener#onClickメソッドに記述します。
  TwitterFactory factory = new TwitterFactory();

  // twitterはクラス変数。
  twitter =
    factory.getOAuthAuthorizedInstance(
      CONSUMER_KEY,
      CONSUMER_SECRET);

  // requestTokenもクラス変数。
  requestToken = twitter.getOAuthRequestToken(CALLBACK_URL);

  // 認証用URLをインテントにセット。
  // TwitterLoginはActivityのクラス名。
  Intent intent = new Intent(this, TwitterLogin.class);
  intent.putExtra("auth_url", requestToken.getAuthorizationURL());

  // アクティビティを起動。
  // REQUEST_CODEは任意のint型の値。
  this.startActivityForResult(intent, REQUEST_CODE);

2.下記コードを、Activity2で取得した値を使って、
access_tokenとaccess_token_secretを取得するために、
onActivityResultメソッドに記述します。
  // インテントからoauth_verifierを取り出して、
  // access_tokenとaccess_token_secretを取得する。
  // この取得処理はTwitter4jが勝手にやってくれます。
  AccessToken accessToken =
    twitter.getOAuthAccessToken(
    requestToken,
    intent.getExtras().getString("oauth_verifier"));

  // 連携状態とトークンの書き込み
  SharedPreferences pref =
    getSharedPreferences(
      PREFERENCE_NAME,
      MODE_PRIVATE);

  SharedPreferences.Editor editor=pref.edit();
  editor.putString("oauth_token",accessToken.getToken());
  editor.putString("oauth_token_secret",accessToken.getTokenSecret());
  editor.putString("status","available");

  editor.commit();

  // 設定おしまい。
  finish();


●Activity2のコーディング例
以下のコードを、ログイン処理を担うActivityのonCreateメソッドに記述します。
このコーディング例では、oauth_verifierを取得して、
Intentを介してActivity1に戻すことを想定しています。
  WebView webView = (WebView)findViewById(R.id.WebView01);

  // 画面遷移時にWebView内で画面遷移するようにする。
  // こうしないと、標準ブラウザが開いてしまう。
  webView.setWebViewClient(new WebViewClient(){

    // ページ描画完了時に呼ばれる。
    public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);

      // CALLBACK_URLは注意点1で書いた適当な文字列。
      // Twitter側でやってくれる処理として、
      // 認証完了したら、指定したCALLBACK URLにリダイレクトするので、
      // 遷移先のURLがCALLBACK URLから始まっていたら、認証成功とみなす。
      if(url != null && url.startsWith(CALLBACK_URL)){
        // URLパラメータを分解する。
        String[] urlParameters = url.split("\\?")[1].split("&");

        String oauthToken = "";
        String oauthVerifier = "";

        // oauth_tokenをURLパラメータから切り出す。
        if(urlParameters[0].startsWith("oauth_token")){
          oauthToken = urlParameters[0].split("=")[1];
        }else if(urlParameters[1].startsWith("oauth_token")){
          oauthToken = urlParameters[1].split("=")[1];
        }

        // oauth_verifierをURLパラメータから切り出す。
        if(urlParameters[0].startsWith("oauth_verifier")){
          oauthVerifier = urlParameters[0].split("=")[1];
        }else if(urlParameters[1].startsWith("oauth_verifier")){
          oauthVerifier = urlParameters[1].split("=")[1];
        }

        // oauth_tokenとoauth_verifierをインテントにセット。
        Intent intent = getIntent();
        intent.putExtra("oauth_token", oauthToken);
        intent.putExtra("oauth_verifier", oauthVerifier);

        // 元のActivityに戻す。
        setResult(Activity.RESULT_OK, intent);
        finish();
      }
    }
  });

 // Activity1で設定した認証ページを表示。
 webView.loadUrl(this.getIntent().getExtras().getString("auth_url"));


ツイート編に続く・・・
このエントリーをはてなブックマークに追加