HerokuでOAuth
こんにちは
成り行きでHerokuのOAuthを使った単純なアプリを作ったので手順をメモしておきます。
★クライアントアプリケーションを登録する
まずはダッシュボードのアカウントページでOAuthを使用するアプリケーションを登録します。
ページの真ん中あたり「Register API Client」のボタンをクリックすると、アプリ名と認証後のリダイレクトURLを入力するフォームが表示されるので適当に設定します。
登録するとclient_idとclient_secretが発行されるので、これらをコピーして環境変数等に設定しておきます。
ちなみにリダイレクトURLは「http://localhost:9000/login」のようにローカルホストをhttpプロトコルで指定しても問題ありません。実運用の場合はインターネット上に公開されたURL(もちろんherokuapp.comでOK)をhttpsで指定するわけですが、ローカルホスト用のアプリとHeroku上のアプリの二つを登録しておけばローカルでテストしたものをgit pushしてすぐに確認できるのでとても楽です。
★PlatformAPIのラッパー
今回サーバーサイドはPlay1.2.6を使用して作成しました。Play2(Scala)も考えたんですが将来的にPlatformAPIのラッパーは汎用ライブラリ化するかも?と思っていて、それを考えたら最初からJavaで書いた方が楽なので。
で、そのプロトタイプコードをGistに公開しています。
Playを使用しているので通信部分にはWSクラスを使用していますが、汎用化する場合はもちろんこの部分は書き換えます。AccountクラスやHerokuApiExceptionなどの本来は単体クラスとするべきものがpublic staticクラスになっているのもプロトタイプとしての割り切りです。
実際に実装したのはgetAccountメソッドとgetRateLimitメソッドの二つだけですが、他のメソッドもほぼ同じパターンで実装可能なはずです。
ちなみにHerokuAPIのJavaラッパーとしてはHeroku社謹製のheroku.jarがありますが、これはAPIKeyを引数にインスタンスを作成するライブラリなのでOAuthでは使用できません。
ざっとドキュメントを見た感じでは、HerokuのWebAPIは
- HerokuAPI
herokuコマンドが内部的に呼び出しているWebAPI。これを利用すればherokuコマンドでやっていることを何でもプログラムから実行できる(はず) - PlatformAPI
OAuth経由でherokuを操作するためのAPI。
の2種類がきっちり区別されていてそれぞれできることが異なります。
待ってたらそのうちPlatformAPIのJavaラッパーも作られると思いますが、そっちが早いか自分が必要に迫られるのが早いか。。。(^^;;;
★コードサンプル
今回作成したアプリのコードは公開されていないので、上記クラスを使用した簡単なコードサンプルを載せておきます。
ログイン用のURLの生成
public static void index() { String clientId = System.getenv().get("HEROKU_OAUTH_ID"); String url = HerokuApi.getOAuthUrl(clientId, HerokuApi.Scope.Identity); render(url); }
クライアントIDとScope(認可を要求する権限の範囲)を引数にHerokuApi#getOAuthUrlメソッドを呼び出すと認証用のURLが返されるのでそれをHTML内にリンクとして配置します。
Scope.Identityはユーザー情報のみにアクセスできるもっとも狭い権限のScopeです。
リダイレクトされたコードからHerokuApiを生成してメソッドを実行
リンクをクリックするとHerokuの認証画面が表示され、そこで「Allow Access」をクリックするとアカウント画面で登録したリダイレクトURLに「code」というURLパラメータをつけてリダイレクトされます。
リダイレクトされた側のコードは以下のような感じです。
public static void login(String code) throws Exception{ String secret = System.getenv().get("HEROKU_OAUTH_SECRET"); HerokuApi api = HerokuApi.authenticate(secret, code); String email = api.getAccount().getEmail(); renderText(email); }
これでログインしたユーザーのメールアドレスが画面に表示されます。
OAuth初期はGoogleやFacebookでまったく思った通りに動かず苦労した記憶があるんですが、仕様がこなれてきたのかもの凄くあっさりと動きました。(^^v
ちなみにもう一個の実装メソッドであるgetRateLimitメソッドはAPIの実行可能回数(PlatformAPIは1時間に1200回までと制限されている)を返すメソッドですが、多分Heroku側がバグっている気がします。(^^;;;(サポート問い合わせ中です。)
コメント