前回、OAuthについてまとめてみたので、今度は実際にOAuth認証を利用したAPIへのアクセスをJavaで実装してみる。
今回は、天下のoauth.netのoauthライブラリ(Google Code)を使う。
oauthのリポジトリからcommons、consumer、httpclient4を持ってくる。
OAuthのライブラリはいくつかあるみたいだけど、Javaのコードを書く場合はAndroidアプリやGoogle App Engineなどにも移植可能なものがよさげ。
(Jakarta Commons HttpClient v4にてOAuth認証を組み込むとコードがすっきりする。一方、GAEではHttp Client v4が使えなかったりする。こういった違いを吸収できるとこがイイ)
やること
いっぱい。。。
- consumer.propertiesを用意
- consumer.propertiesを読み込む
- リクエストトークンを取得する
- ユーザーにアプリケーションを承認してもらう
- アクセストークンを取得する
consumer.propertiesを用意
まず、サービスプロバイダーのエンドポイント情報やコンシューマの情報を、下記のようなconsumer.propertiesファイルに定義する。(適当な名前を付ける。例ではtomokey)
- tomokey.consumerKey: consumer_key
- tomokey.consumerSecret: consumer_secret
- tomokey.callbackURL: oob
- tomokey.serviceProvider.baseURL: https://www.google.com/
- tomokey.serviceProvider.requestTokenURL: /accounts/OAuthGetRequestToken
- tomokey.serviceProvider.userAuthorizationURL: /accounts/OAuthAuthorizeToken
- tomokey.serviceProvider.accessTokenURL: /accounts/OAuthGetAccessToken
Google Data APIをWebアプリケーションから利用する場合
consumer key | 発行されたもの |
consumer secret | 発行されたもの |
callback URL | verifierを受け取るURL |
request token URL | https://www.google.com/accounts/OAuthGetRequestToken |
user authorization URL | https://www.google.com/accounts/OAuthAuthorizeToken |
access token URL | https://www.google.com/accounts/OAuthGetAccessToken |
Google Data APIをクライアントアプリケーションから利用する場合
consumer key | anonymous |
consumer secret | anonymous |
callback URL | oob |
request token URL | https://www.google.com/accounts/OAuthGetRequestToken |
user authorization URL | https://www.google.com/accounts/OAuthAuthorizeToken |
access token URL | https://www.google.com/accounts/OAuthGetAccessToken |
consumer.propertiesを読み込む
- // クラスローダーを生成
- ClassLoader loader = ClassLoader.getSystemClassLoader();
- // 設定ファイルのURLを取得
- URL url = loader.getResource("consumer.properties");
- // 読み込み
- Properties prop = ConsumerProperties.getProperties(url);
- // tomokeyという名前の付いた設定を読み込む
- ConsumerProperties consumers = new ConsumerProperties(prop);
- OAuthConsumer consumer = consumers.getConsumer("tomokey");
リクエストトークンを取得する
- // OAuthClient
- OAuthClient client = new OAuthClient(new HttpClient4());
- // OAuth accessor
- OAuthAccessor accessor = new OAuthAccessor(consumer);
- // パラメータを構築
- List<Parameter> params = new ArrayList<Parameter>();
- // oauth_callbackを追加
- params.add(new Parameter(
- OAuth.OAUTH_CALLBACK,
- accessor.consumer.callbackURL));
- // リクエストトークン取得を要求
- client.getRequestToken(accessor, "GET", params);
- // 取得したリクエストトークン
- String token = accessor.requestToken;
- String secret = accessor.tokenSecret;
- base stringの構築
- これらの文字列を全部連結する。
- HTTPリクエストメソッド(POSTとかGET)
- アクセスURL
- 全リクエストパラメータを「key=value」形式にしてkeyでソートして「&」でくっつける…
- HTTPリクエストメソッド(POSTとかGET)
- oauth_signatureの構築
- デフォルトのSHA-1アルゴリズムでbase stringに対するハッシュ値を計算し、base64エンコードをかけて生成する。
- SHA-1の鍵にはconsumer secretの末尾に「&」を付与したものを用いる。
- HTTPリクエストの構築と実行
- oauth_signatureを含む全てのパラメータをBODY部に設定し、Content-Type:application/x-www-form-urlencodedとしてリクエストを発行する。
- APIに依っては、パラメータをHEADER部に行わなければならない場合もあるので、consumer.propertiesに「tomokey.consumer.parameterStyle: AUTHORIZATION_HEADER」とか設定すると吉。
ユーザーにアプリケーションを承認してもらう
これはアプリケーションの形態に依存すると思う(Androidアプリならhttp/httpsのインテントを投げるとか)けど、いずれにしても下記のように作成したURLに対して、ブラウザでアクセスしてもらう必要がある。
- // サービスプロバイダーが定義しているエンドポイント
- String authUrl
- = accessor.consumer.serviceProvider.userAuthorizationURL;
- // ここで作成したURLにアクセスしてもらう
- String url
- = OAuth.addParameters(authUrl, OAuth.OAUTH_TOKEN, token);
クライアントアプリケーション(callbackURLがoob)の場合は、画面にverifierが表示される。(ユーザーにコピペしてもらう必要がある)
アクセストークンを取得する
- // OAuthClient
- OAuthClient client = new OAuthClient(new HttpClient4());
- // OAuth accessor
- OAuthAccessor accessor = new OAuthAccessor(consumer);
- // SHA1の鍵にリクエストトークンのシークレットのほうが必要
- accessor.tokenSecret = secret;
- // パラメータを構築
- List<Parameter> params = new ArrayList<Parameter>();
- // oauth_tokenとしてリクエストトークンを追加
- params.add(new Parameter(
- OAuth.OAUTH_TOKEN,
- token));
- // oauth_verifierを追加
- params.add(new Parameter(
- OAuth.OAUTH_VERIFIER,
- "ベリファイア"));
- // アクセストークン取得を要求
- client.getAccessToken(accessor, "GET", params);
- // 取得したアクセストークン
- String accToken = accessor.accessToken;
- String accSecret = accessor.tokenSecret;
- accessor.tokenSecretにリクエストトークンのシークレットのほうを設定する。(SHA1ハッシュ計算時に使う鍵として利用)
- リダイレクトかコピペかで入力してもらったベリファイアをパラメータとして設定する。
終わり
一応、アクセストークンを使ってAPIアクセスするコードものっけておく。
- // URL(Fusion Tables API)
- String url = "https://www.google.com/fusiontables/api/query";
- // パラメータ
- List<Parameter> params
- = OAuth.newList("sql", "SELECT * FROM 913439");
- // OAuthClient
- OAuthClient client = new OAuthClient(new HttpClient4());
- // OAuth accessor
- OAuthAccessor accessor = new OAuthAccessor(consumer);
- // アクセストークンを設定
- accessor.accessToken = accToken;
- accessor.tokenSecret = accSecret;
- // リクエストオブジェクト生成
- OAuthMessage request
- = accessor.newRequestMessage("POST", url, aParams);
- // 実行
- OAuthMessage response
- = client.access(request, ParameterStyle.AUTHORIZATION_HEADER);
ライブラリにして公開した
すぐ上に書いてあるリダイレクトの考慮をした上で、ちょっと便利っぽくライブラリにまとめてみた。 ここ(Google Code)からダウンロード可能。
0 件のコメント:
コメントを投稿