8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Android アプリでZaimのOAuth 認証を行う

Last updated at Posted at 2014-11-25

Zaim開発センターへ登録

Zaim開発センターへログインし、OAuth認証したいアプリケーションを登録する。
登録後、下記情報が表示される。認証の際に使用するので記憶しておく。

  • Consumer Key
  • Consumer Secret
  • Request token URL
  • Authorize URL
  • Access token URL

oauth-signpostをimportする

今回はOAuth認証のライブラリにoauth-signpostを使用する。
build.gradleに下記記述を追加し、ライブラリを使用できるようにする。

build.gradle
dependencies {
    // 以下を追加
    compile 'oauth.signpost:signpost-core:1.2'
    compile 'oauth.signpost:signpost-commonshttp4:1.2'
}

oauth-signpostを使用したOAuth認証手順概要

  1. OAuth認証に使用するオブジェクトの生成
  2. 認証ページのURLを取得する
  3. 認証ページを表示する
  4. 認証結果からアクセストークンを取得する
  5. 取得したアクセストークンを用いて通信を行う

OAuth認証を行う

OAuth認証に使用するオブジェクトの生成

ここで、Zaim開発センターで登録した際に取得できる情報を入力する。

LoginActivity.java
private static final String CONSUMER_KEY = "<<Zaim開発センター登録時の情報>>";
private static final String CONSUMER_SECRET = "<<Zaim開発センター登録時の情報>>";
private static final String REQUEST_TOKEN_URL = "<<Zaim開発センター登録時の情報>>";
private static final String AUTHORIZE_URL = "<<Zaim開発センター登録時の情報>>";
private static final String ACCESS_TOKEN_URL = "<<Zaim開発センター登録時の情報>>";

private OAuthConsumer mConsumer;
private OAuthProvider mProvider;

mConsumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
mProvider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL);

認証ページのURLを取得する

OAuthProviderオブジェクトのretrieveRequestTokenメソッドを使用して認証ページのURLを取得する。
retrieveRequestTokenメソッドを呼び出す際に、コールバックのURLを指定するが今回はコールバックは使わないので適当なURLを指定する。

LoginActivity.java
    public interface RequestCallback {
        public void onComplete(String authUrl);
    }

    private class OAuthRequestAsyncTask extends AsyncTask<Void, Void, Void> {

        private RequestCallback mCallback;
        private String mCallbackUrl;
        private String mAuthUrl;

        OAuthRequestAsyncTask(String callbackUrl, RequestCallback callback) {
            mCallbackUrl = callbackUrl;
            mCallback = callback;
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            //OAuth認証
            try {
                mAuthUrl = mProvider.retrieveRequestToken(mConsumer, mCallbackUrl);
            } catch (OAuthMessageSignerException e) {
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void v) {
            mCallback.onComplete(mAuthUrl);
        }
    }

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

OAuthProviderオブジェクトのretrieveAccessTokenメソッドを使用してアクセストークンを取得する。
retrieveAccessTokenメソッドの引数には、認証後取得できるOAuth Verifierコードを渡す。

LoginActivity.java
    public interface AccessCallback {
        public void onComplete();
    }

    private class OAuthAccessAsyncTask extends AsyncTask<Void, Void, Void> {

        private AccessCallback mCallback;
        private String mOAuthVerifier;

        OAuthAccessAsyncTask(String oauthVerifier, AccessCallback callback) {
            mOAuthVerifier = oauthVerifier;
            mCallback = callback;
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            try {
                // AccessToken取得
                mProvider.retrieveAccessToken(mConsumer, mOAuthVerifier);

            } catch (OAuthMessageSignerException e) {
                e.printStackTrace();
            } catch (OAuthNotAuthorizedException e) {
                e.printStackTrace();
            } catch (OAuthExpectationFailedException e) {
                e.printStackTrace();
            } catch (OAuthCommunicationException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void v) {
            mCallback.onComplete();
        }
    }

Login画面を作る

ネットアクセスの権限を付ける。

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

Login画面にはWebViewを配置する。
このWebViewにログインページを表示し、この画面を通してログインを行う。

activity_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".LoginActivity">

    <WebView
        android:id="@+id/web_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

認証後のページからOAuth Verifierコードを取得するためのWebViewのsetWebViewClientメソッドを使ってJavaScriptコードを埋め込んでいる。
アラートで抜き出したコードをWebChromeClientのonJsAlertのコールバックを利用して取得する。

LoginActivity.java

        final WebView webView = (WebView) findViewById(R.id.web_view);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                Log.v(this.getClass().getName(), "onPageFinished url = " + url);

                if (url.equals(LOGIN_COMPLETE_URL)) {
                    // 認証が完了したら、ページ内からOAuth Verifierコードを抜き出してアラートとして表示する
                    webView.loadUrl("javascript:window.alert(document.getElementsByTagName(\'code\')[0].innerHTML);");
                }
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                Log.d(TAG, "url = " + url);
                Log.d(TAG, "message = " + message);

                // 上のonPageFinishedで埋め込んだjavascriptでOAuth Verifierのコードが取得できる。
                // このコードを利用してAccessTokenを取得する。
                String oauthVerifier = message;
                OAuthAccessAsyncTask asyncTask = new OAuthAccessAsyncTask(oauthVerifier, new AccessCallback() {
                    @Override
                    public void onComplete() {
                        // OAuthConsumerからTokenとTokenSecretが取得できる
                        Log.d(TAG, "ACCESS_TOKEN : " + mConsumer.getToken());
                        Log.d(TAG, "ACCESS_TOKEN_SECRET : " + mConsumer.getTokenSecret());
                    }
                });
                asyncTask.execute();

                return true;
            }
        });

        // 認証ページのURLを取得する
        OAuthRequestAsyncTask asyncTask = new OAuthRequestAsyncTask(CALLBACK, new RequestCallback() {
            @Override
            public void onComplete(String authUrl) {
                Log.d(TAG, "authUrl = " + authUrl);
                
                // 取得したURLを表示する
                webView.loadUrl(authUrl);
            }
        });
        asyncTask.execute();

認証後の通信

ユーザ情報を取得するAPIのHTTP GETリクエストを作成するには下記のように、送信する前に署名を行う。

    HttpClient httpClient = new DefaultHttpClient();
    String urlString = "https://api.zaim.net/v2/home/user/verify";
    
    HttpGet httpGet = new HttpGet(urlString);
    // HTTP GETリクエストを署名する
    mConsumer.sign(httpGet);

    // HTTP GETリクエストを送信
    ...

サンプルコード

8
14
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
8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?