LoginSignup
45
47

More than 5 years have passed since last update.

Android アプリで OAuth 認証する

Last updated at Posted at 2013-10-20

Android(というかJava)で OAuth 認証を実装してみたので、手順をメモしました。
ここでは OAuth1.a での認証を想定してます。

1. OAuthライブラリをダウンロードする

OAuth とりわけ1.aは手順が複雑なので、ライブラリを使ったほうが楽です。
Java で使えるライブラリは、以下のようなものがあるみたいです。

※以降は oauth-signpost の実装例です。

上記URLから次の2つをダウンロードします。
(下記バージョンは、2013/10/17時点での最新です。)

  • signpost-core-1.2.1.2.jar
  • signpost-commonshttp4-1.2.1.2.jar

これらを Android プロジェクトに import します。

2. 認証するサービスの開発者登録をする

OAuth 認証するためには、ConsumerKey と ConsumerSecret の情報が必要です。
それらを取得するために、OAuth認証をするサービスの開発者サイトで、開発者登録をします。すると上記2つの情報に加え、アクセス先URLなどの情報も得ることが出来ます。

この後必要になるのは、主に以下の情報です。

  • Consumer key
  • Consumer secret
  • Request token URL
  • Authorize URL
  • Access token URL
  • Callback URL

3. ブラウザでユーザーに OAuth 認証してもらうコード

ユーザーのアカウント情報で OAuth 認証してもらうにあたり、ブラウザで認証画面を表示させるようにします。(ログイン画面を作る手間がかからないので。)
以下は該当する箇所のみ、抜粋したものです。

MainActivity.java
public class MainActivity extends Activity {

    private static final String CONSUMER_KEY = "xxxx";
    private static final String CONSUMER_SECRET = "xxxx";
    private static final String REQUEST_TOKEN_URL = "xxxx";
    private static final String AUTHORIZE_URL = "xxxx";
    private static final String ACCESS_TOKEN_URL = "xxxx";
    private static final String CALLBACK = "xxxx";

    private OAuthConsumer mConsumer;
    private OAuthProvider mProvider;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Oauth認証を開始
        OAuthRequestAsyncTask oAuthAsyncTask = new OAuthRequestAsyncTask();
        oAuthAsyncTask.execute();
    }

    /**
     * OAuth認証の通信を行うクラス
     */
    private class OAuthRequestAsyncTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void...arg0) {
            // Oauth認証
            try {
                mConsumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
                mProvider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL);
                String authUrl = mProvider.retrieveRequestToken(mConsumer, CALLBACK);
                // ブラウザに認証ページを開かせる
                MainActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
            } catch (OAuthMessageSignerException e) {
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

4. 認証結果からアクセストークンを取得する

まずはブラウザからのコールバックを受け取れるように、AndroidManifest.xml に Intent-filter を定義します。

AndroidManifest.xml
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleInstance" >
            <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="xxxx" android:host="xxxx" />
            </intent-filter>
        </activity>

<data> で定義するのは、3 で定義している CALLBACK の URL と同じものを定義します。
例えば、 myapp://callback という CALLBACK であれば、 scheme="myapp"host="callback" となります。
launchMode="singleInstance" は、何個も同じActivityを生成しないようにするための宣言です。

アクセストークンを取得するためのコールバック処理は、以下のようになります。

MainActivity.java
    /**
     * Intentからの起動
     * @param intent
     */
    @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        Uri uri = intent.getData();
        // ブラウザ認証からのコールバック処理
        if (uri != null && uri.toString().startsWith(CALLBACK)) {
            // アクセストークン取得およびリクエスト処理
            OAuthAccessAsyncTask oAuthAccessAsyncTask = new OAuthAccessAsyncTask();
            oAuthAccessAsyncTask.execute(uri);
        }
    }

    /**
     * OAuth認証のコールバック処理を行うクラス
     */
    private class OAuthAccessAsyncTask extends AsyncTask<Uri, Void, Void> {
        @Override
        protected Void doInBackground(Uri...uris) {
            Uri uri = uris[0];
            final String oauthVerifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
            try {
                // AccessToken取得
                mProvider.retrieveAccessToken(mConsumer, oauthVerifier);
                Log.d(TAG, "ACCESS_TOKEN : " + mConsumer.getToken());
                Log.d(TAG, "ACCESS_TOKEN_SECRET : " + mConsumer.getTokenSecret());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

上記で Log に出力している AccessToken を使ってリクエストを送信するので、取得後は保存しておくと使い回しがし易いです。

5. OAuth認証結果を使ってAPIを呼び出す

APIを実際に呼び出す際には、リクエストデータを以下のように署名してから送信します。

MainActivity.java
        HttpClient httpClient = new DefaultHttpClient();
        String urlString = "xxxx";

        HttpGet httpGet = new HttpGet(urlString);
        // リクエストデータを署名する
        mConsumer.sign(httpGet);

        String responce = httpClient.execute(httpGet,
                new ResponseHandler<String>() {
                    @Override
                    public String handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
                        // HttpStatus.SC_OK (HTTP200)
                        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                            return EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
                        }
                        return null;
                    }
                });
        Log.d(TAG, "responce : " + responce);
45
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
47