ネイティブアプリで実践! mixi Graph API活用法
ネイティブアプリで実践! mixi Graph API活用法


OAuth 2.0を使う
ソーシャルなAndroidアプリの作り方


株式会社ミクシィ
システム本部 技術部 たんぽぽグループ 藤崎 友樹
プラットフォームサービス開発部 鶴原 翔夢
2011/3/30

リダイレクト先のURL(独自スキーマ)の定義

- PR -

 アプリケーション上のログインボタンが押下されると、次のような認可画面のURLを生成して、暗黙的なIntentを発行し、Webブラウザに遷移します。

 scopeには、これからユーザーに認可を求めるリソースのスコープを空白区切りで指定します。今回は、People APIを用いて友人一覧を取得するため、「r_profile」を指定します。

https://mixi.jp/connect_authorize.pl?reponse_type=code&client_id=【Consumer Key】&scope=【Scope】

 このURLを開くことで、アプリケーション側の処理はいったん終了です。

  OAuthClient.java抜粋
private static final String AUTHORIZE_URL = "https://mixi.jp/connect_authorize.pl";
private static final String[] SCOPE = { "r_profile" };
 
/** Webブラウザを起動し、認証認可手順を開始するためのURLへ遷移
 * @param context 呼び出し元の {@link Context}
 */
public static void initiateLoginProcess(Context context) {
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.setData(buildAuthorizeUri());
    context.startActivity(i);
}
 
/** 認可ページの URL を生成 */ 
private static Uri buildAuthorizeUri() {
    return Uri.parse(AUTHORIZE_URL).buildUpon()
        .appendQueryParameter("client_id", EncodedConsumerKey.getClientId())
        .appendQueryParameter("response_type", "code")
        .appendQueryParameter("scope", TextUtils.join(" ", SCOPE).toString())
        .build();
}

 この後、サイト上でのログイン認証とアプリケーションに対する認可の処理はWebブラウザに一任されます。立ち上がったWebブラウザではまず、ログインページが表示されます。

 すでにユーザーのWebブラウザのCookie上にログイン済みのセッションが存在する場合は、直接、以下の認可画面が表示されます。また、ユーザーのログインセッションが確立した後も、以下の認可画面が表示されます。

 ここでユーザーに対して、アプリケーションの情報と使用するリソースを列挙して、その認可を求めます。ユーザーが「同意する」ボタンを押下すると、Authorization Codeを「code」クエリパラメータに含めたリダイレクトURLに遷移します。

Webブラウザからのリダイレクトを受け取る

 今回のサンプルのリダイレクト先は、次のようなURLとして構成されます。

org.example.android.oauth://callback?code=347ab1db9398d60b5ef3515e672d1e

 Android端末上で発生したこのURLへの遷移(暗黙的なIntent)を、アプリケーションで受信するには、「AndroidManifest.xml」にIntent Filterを記述します。URLを受け取る<activity>タグの要素として次のような<intent-filter>タグを記述します。

  AndroidManifest.xml抜粋
    <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="org.example.android.oauth" android:host="callback" /> <!-- 【1】 -->
</intent-filter>

 【1】行の<data>タグの「android:scheme」属性に、アプリケーション登録時に設定したリダイレクトURLのスキームを設定します。それ以外の属性も必要に応じて設定します。これで、端末内でこのスキームのURLへの遷移が発生した(Intentが発行された)場合、このActivityが起動されるようになります。

 また、ログインを行う画面の<activity>タグには、下記【2】行のように「android:launchMode」を指定します。

  AndroidManifest.xml抜粋
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask" <!-- 【2】 -->
android:configChanges="orientation|keyboardHidden"
>

 無指定(standard)の場合、Webブラウザからリダイレクトが発生した際に、別の新しいActivityインスタンスが生成され、認可前・後の両方のActivityがスタック上に存在する状態になります。singleTaskに設定すると、リダイレクト時に、呼び出し元のActivityがそのままスタックの先頭に移動され、「Activity#onNewIntent(Intent)」メソッドでIntentが渡されます。

 詳細については、Androidのドキュメントをご参照ください。

 受け取ったIntentから、Authorization Codeを含むURIオブジェクトを取り出すには、「Activity#getIntent()」メソッド、あるいは「Activity#onNewIntent(Intent)」メソッドで、「Intent#getData()」メソッドを呼び出します。

  MainActivity.java抜粋
private boolean parseIntent(Intent intent) {
    // Intent の action を確認
    String action = intent.getAction();
    if (action == null || !action.equals(Intent.ACTION_VIEW)){
        return false;
    }
    // Uri を取り出す
    Uri uri = intent.getData();
    if (uri == null) {
        return false;
    }
    // code パラメータから Authorization Code を取り出す
    String code = uri.getQueryParameter("code");
    if (code == null) {
        showToast(R.string.auth_error_login_failed);
        return false;
    }
    // トークンの取得開始
    new TokenRetriever().execute(code);
    return true;
}

認可コードからAccess Tokenを受け取る

 IntentからAuthorization Codeを取り出すことに成功したら、それをAccess Tokenに交換します。ここでは、通信を行うためにAndroidManifest.xmlに以下の行の追加が必要です。

    <uses-permission android:name="android.permission.INTERNET" />

 通信をメインスレッドで行うと、処理完了まで画面操作が一切行えなくなるため、AsyncTaskを使って処理を非同期化します。少し長くなってしまうため、コードは掲載しませんが、サンプルのソースコードの「MainActivity.TokenRetriever」を参照してください。

 また、Webブラウザから遷移した直後、アプリケーションの見た目は最初の起動時と同じ画面となり、何が起きたかが分かりにくい状況となります。ユーザー向けには、ProgressDialogなどを用いて、目立つ形でログイン処理中である旨を表示します。

 Access Tokenの取得は、HTTPSのエンドポイントに対してPOSTリクエストを発行して行います。このとき送信する情報は、次の通りです。

grant_type="authorization_code"
client_id=【Consumer Key】
client_secret=【Consumer Secret】
redirect_uri=【登録したリダイレクトURL】
code=【取得したAuthorization Code】

 このリクエストの結果として、HTTPのレスポンスコードおよびJSONが返されます。JSONには、access_tokenとrefresh_token、access_tokenが失効するまでの秒数(expires_in)が含まれるため、これらの情報をSharedPreferencesなどのストレージに保存します。

 これらの実装は、サンプルコードの「MainActivity.TokenRetriever」クラスや「OAuthClient#getTokenFromAuthorizationCode()」メソッド、「OAuthClient.TokenResponseHandler」クラス、「ApiRequestUtils.doPostRequest()」メソッドを参照してください。

 次ページでは引き続き、OAuth 2.0を用いた認証および認可の流れと、取得したAccess Tokenを使用してAPIリクエストを行い結果を表示するまでの、一通りの実装を解説し、続いて、Access Tokenの有効期限に関する扱いについて、実装を交えつつ説明していきます。

2/3

 INDEX
ネイティブアプリで実践! mixi Graph API活用法 
OAuth 2.0を使うソーシャルなAndroidアプリの作り方
  Page1
「OAuth」を使ってスマートでソーシャルなアプリを作ろう
mixi Graph APIの利用登録
Page2
リダイレクト先のURL(独自スキーマ)の定義
Webブラウザからのリダイレクトを受け取る
認可コードからAccess Tokenを受け取る
  Page3
Access Tokenを用いてPeople APIへリクエストを発行
Access Tokenの有効期限が切れた場合の処理
Refresh Tokenが無効になった場合
アプリにソーシャルな要素を取り入れてみまソ


 Smart&Social フォーラム トップページへ



Smart & Social フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Smart & Social 記事ランキング

本日 月間