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


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


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

Access Tokenを用いてPeople APIへリクエストを発行

- PR -

 Access Tokenの取得まで完了したら、いよいよPeople APIへリクエストを発行します。

 People APIで友人一覧を取得するには、次のURLへGETリクエストを発行します。

http://api.mixi-platform.com/2/people/@me/@friends

 Access Tokenは、リクエストヘッダのAuthorizationヘッダとして「OAuth a1b2c3……」という形でセットします。

  ApiRequestUtils.java抜粋
    if (store != null) {
        // token を取得
        token = getValidAccessToken(store);
        if (token != null) {
            // Authorization ヘッダを付与
            authorizationHeader = 
                new BasicHeader("Authorization", "OAuth " + token.accessToken);
            request.addHeader(authorizationHeader);
        }
    }

 ヘッダを付与した状態でGETリクエストを行い、成功すると結果としてJSONが返されます。JSONは、次のようなコードでJSONObjectを利用してパースし、結果をArrayListへ格納します。今回のサンプルでは、返されたdisplayNameとprofileUrlのみ取り出しています。

  PeopleApiClient.java抜粋
private PeopleApiResponse parsePeopleFromResponse(String string) {
PeopleApiResponse res = new PeopleApiResponse();
ArrayList<MixiPerson> people = new ArrayList<MixiPerson>();
try {
// 外側
JSONObject json = new JSONObject(string);
res.itemsPerPage = json.getInt("itemsPerPage");
res.startIndex = json.getInt("startIndex");
res.totalResults = json.getInt("totalResults");

// 内側(結果のリスト)
JSONArray entries = json.getJSONArray("entry");
int count = entries.length();
for (int i = 0; i < count; i++) {
JSONObject entry = entries.getJSONObject(i);

MixiPerson person = new MixiPerson();
person.displayName = entry.getString("displayName");
person.profileUrl = entry.getString("profileUrl");

people.add(person);
}
res.entry = people;

return res;
} catch (JSONException e) {
Log.w(TAG, "something went wrong while parsing json", e);
}
return null;
}

 後は、取得できた内容をListViewへセットします。ListViewには、ArrayAdapterをセットしておきます。また、友人が多い場合はページングにて次のn件を取得するため、「ListView#addFooterView」メソッドで末尾要素として「続きを取得」という要素を追加しておきます。

  MainActivity.java抜粋
    // リストの末尾要素(続きを取得/読み込み中)の構成
mFooterView = createFooterView();
mFooterLoadingView = createFooterLoadingView();

// リストの構成
mListView = (ListView) findViewById(android.R.id.list);
mListView.setOnItemClickListener(this);
mListView.addFooterView(mFooterView, null, true);

// リストにセットするアダプタ
mAdapter = new ArrayAdapter<MixiPerson>(this,
android.R.layout.simple_list_item_1, android.R.id.text1);
mListView.setAdapter(mAdapter);

 このAdapterに対して、取得した要素をaddします。Adapter#addで要素を追加すると、その結果は自動的にListViewにも反映され、以下の図のようにユーザーの友人一覧が表示されます。

 その他、MainActivity上での画面やListAdapterの処理は、ASyncTaskを継承した「MainActivity.PeopleLoaderTask」クラスで、APIのリクエストやレスポンスの処理は、「PeopleApiClient」クラスに記述していますので、適宜ご参照ください。

Access Tokenの有効期限が切れた場合の処理

 Access Tokenには有効期限があります。期限が過ぎると、そのトークンは利用できなくなります。利用期限が過ぎた場合は、トークンのリフレッシュを行い、新しいAccess Tokenを取得する必要があります。

 利用期限は、トークンの取得時のexpires_inから算出して求められるほか、実際にリクエストを発行した際に、レスポンスとしてHTTPステータスコード「401 Authorization Required」とともに、次のヘッダが付与されることで判別できます。

WWW-Authenticate: OAuth error='expired_token'

 このレスポンスを受け取った場合、トークンをリフレッシュしてからリクエストを再試行する必要があります。トークンのリフレッシュは、前述のAuthorization CodeからAccess Tokenを取得する処理と、次の2点が異なる以外は同じ処理となります。

  1. grant_typeが「refresh_token」
  2. 「redirect_uri」「code」の代わりに「refresh_token」を指定する

 ただ、難しくない処理とはいえ、APIのリクエスト処理を書くたびに、毎回トークンのリフレッシュ機構を書くのは面倒です。API呼び出しのHTTPリクエストを1層ラップして、リクエストの際に自動的にAuthorizationヘッダを付与し、必要であればトークンのリフレッシュも行うように実装しておくと便利です。

 今回のサンプルでは、その処理を行う「ApiRequestUtils.executeRequestWithRefresh()」メソッドを、次のように実装しています。

  ApiRequestUtils.java抜粋
private static <T> T executeRequestWithRefresh(HttpRequestBase request,ResponseHandler<T> responseHandler, OAuthTokenStore store, boolean isRetry)
throws ClientProtocolException, IOException {
OAuthToken token = null;
Header authorizationHeader = null;
if (store != null) {
token = getValidAccessToken(store);
if (token != null) {
authorizationHeader =
new BasicHeader("Authorization", "OAuth " + token.accessToken);
request.addHeader(authorizationHeader);
}
}
try {
return executeRequest(request, responseHandler);
} catch (TokenExpiredException e) {
if (!e.isRetryable()) {
Log.w(TAG, "Access token is invalid.");
} else {
if (isRetry) {
Log.e(TAG, "An error occured while trying to refresh the access token.");
} else {
// try to refresh
Log.v(TAG, "Access token has been expired. Trying to refresh.");
if (authorizationHeader != null)
request.removeHeader(authorizationHeader);
store.setToken(OAuthClient.refreshToken(token.refreshToken));
return executeRequestWithRefresh(request, responseHandler, store, true);
}
}
throw e;
}
}

Refresh Tokenが無効になった場合

 ユーザーがサイト上から認可を取り下げた場合や、当初の認可画面で設定された期限が過ぎた場合、Refresh Tokenも無効となります。この場合は、認可フローを最初からやり直す必要があるため、その旨をユーザーに通知し、処理を行う必要があります。

  MainActivity.java抜粋
    PeopleApiClient client = new PeopleApiClient(MainActivity.this);
    try {
        return client.getFriends(startIndex, FETCH_COUNT_PER_REQUEST);
    } catch (TokenInvalidException e) {
        Log.w(TAG, "token is no longer valid");
        // トークンが無効になり、リフレッシュもできない場合は、再ログインが必要
        mNeedRelogin = true; 
    } catch (ClientProtocolException e) {
        Log.w(TAG, "request failed", e);
        errorMessage = e.getLocalizedMessage();
    } catch (IOException e) {
        Log.w(TAG, "request failed", e);
        errorMessage = e.getLocalizedMessage();
    }
    return null;

アプリにソーシャルな要素を取り入れてみまソ

 本稿では、Androidアプリケーションで外部サービス連携を行う際に必須の技術となるOAuth 2.0について概要を説明し、ネイティブ・アプリケーションでOAuth 2.0を用いた外部連携を行う方法を見てきましたが、いかがでしたでしょうか。

 冒頭でも述べたように、外部との連携をうまく使うことでユーザーに大きなメリットをもたらすことができます。本稿のアプリケーションを基に、皆さんのアプリにもソーシャルな要素を取り入れてみてはいかがでしょうか。

■ @IT関連記事


今日から始める! Androidケータイアプリ作成の基礎
いまこそ知っておきたい「Androidアプリ」とは 日に日に国内でのニュースが増えているAndroidケータイ。その特徴を押さえてアプリ作成を始めるための基礎を紹介します
Smart & Social」フォーラム 2009/11/19
Androidで動く携帯Javaアプリ作成入門
本連載で、SDKとEclipseを使ってAndroidの携帯端末で動くJavaアプリを作成し、Android Marketでの配布を目指しましょう
Smart & Social」フォーラム
スマートフォンで「できちゃうこと」って?
イチから始める! Androidセキュリティ(1)
 Androidに潜む危険はマルウェアだけはありません。実はアプリの作り方にも注意が必要です。クウと一緒に学びましょう
Security&Trust」フォーラム 2011/3/3
Androidアプリで高速描画チューニングをするコツ
インタビュー特集:Google直伝!(1) Googleのさまざまなサービスを使いこなすコツをグーグル担当者に聞くインタビュー。初回は日本で端末販売がせまるAndroidについて
リッチクライアント & 帳票」フ ォーラム 2009/4/21
Androidのオープン性でガラパゴスから脱出しよう
ものになるモノ、ならないモノ(29)
 ガラパゴスとやゆされる日本の高機能ケータイ。閉塞感に満ちた国内市場から世界に出るための解は、Androidのオープン性にある
Master of IP Network」フォーラム 2008/12/1

ケータイ分野以外の組み込みデバイス開発の現場でも注目を集めている「Android」。組み込みデバイスへの適用からアプリケーション開発、イベントレポート、ニュースなどAndroidに関するさまざまな技術情報・最新動向をお届けします!

3/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 記事ランキング

本日 月間
ソリューションFLASH