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に公開しています。

HerokuApiラッパーのプロトタイプ

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パラメータをつけてリダイレクトされます。

Herokuoauth

リダイレクトされた側のコードは以下のような感じです。

 

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側がバグっている気がします。(^^;;;(サポート問い合わせ中です。)

コメント(0)