GAE/GoでFirebase Service Account 機能を扱うためのライブラリを公開しました

# GAE/Fire について

@eaglesakura です。

githubにて、[以前記事に書いた認証周り](http://qiita.com/eaglesakura/items/88a487be4f3b5249b6e6)+αを行うライブラリ [GAE/Fire](https://github.com/eaglesakura/gaefire) を公開しました。

機能一覧や使い方はREADMEに書いてある通りで、主にFirebase Custom Authenticationやモバイルアプリと統合して利用することを前提としています。

GAE/Fireを利用することで、下記のような利点があります

 * クライアント(Android等)のAuth Token管理をFirebase SDKに行わせることができる
 * サーバー(GAE/Go)が独自にAuth関連機能を持つ必要がない
 * FirebaseのユーザーIDを任意の文字列にできる(Firebase Custom Tokenを使用した場合)
 * Firebase DatabaseやStorageに任意のRuleデータを追加できる(Firebase Custom Tokenを使用した場合)

# 実装済機能一覧

 * [Json Web Token(JWT)](https://jwt.io/) 管理
  - [x] [Firebase Custom Authentication](https://firebase.google.com/docs/auth/) のためのToken Generate / Verify(カスタマイズしたclaim情報に対応)
  - [x] Firebaseが発行したTokenのVerify
  - [x] [Google Id Token](https://developers.google.com/identity/sign-in/web/backend-auth) のVerify
 * OAuth2 Token管理
  - [x] Service Account権限を持ったOAuth2 Token Generate / Refresh / Verify
  - [x] Google Play Service(Android)にて発行された access_code からOAuth2 TokenのGenerate / Refresh / Verify
  - [x] MemcacheによるToken Cache
 * [Cloud Endpoints 2.0相当](https://cloud.google.com/endpoints/)の認証サポート
  - [x] [Service Control API](https://cloud.google.com/service-control/how-to) を経由した [Google Cloud Console API Key](https://console.developers.google.com/apis/dashboard) のVerify
  - [x] `Authorization` HeaderのVerify / Google Cloud Endpoints 2.0互換 `X-Endpoint-API-UserInfo` Header Generate
  - [x] `swagger.json` に基づいたOAuth2 audience verify
  - [x] `swagger.json` に基づいたGoogle Id Token audience verify
  - [ ] TODO: `swagger.json` に基づいたPath単位での認証ON/OFF

# Cloud Endpoints 2.0認証について

Cloud Endpoints 2.0という機能が最近GAE/JやFlex Environmentに入りました。これは高性能なログ機能なほかに、認証周りのサポートも行ってくれます。
前回の記事の通り、JWTやOAuth2による認証の際には`aud`や`iss`等幾つかの必須チェックがありますが、Cloud Endpoints 2.0ではnginxベースのProxy、もしくはGoogleが提供するフレームワーク部分が全てそれらを代行してくれるようです。
また、GCPのコンソールによって発行されたAPI Keyのverify機能も提供されています。

この記事を書いている時点で、Cloud Endpoints 2.0はGAE/Go Std Environmentに対して提供されていません。ですが認証周りはREST APIによって再現可能でしたので、GAE/Fireでは認証情報のVerifyを提供しています。

GAE/Fireがサポートしている認証形式は下記です。
`aud`及び`iss`相当のデータをチェックを行うため、第三者が勝手に生成したTokenはerrorとして扱います。

 * `Authorization: Bearer {google-id-token(Google sign-in)}`
 * `Authorization: Bearer {firebase-auth-json-web-token(Firebase SDK)}`
 * `Authorization: Bearer {json-web-token(GAE/Fire)}`
 * `Authorization: Bearer {google-oauth2-token}`
 * API Key(query|header)

# ユースケース

下記のような認証トークンの流れを想定しています。
Firebase-Auth等に使われるjson-web-tokenはヘッダ自体にユーザー情報を含んでいるので、Datastore等のアクセスを行う必要がなく、安価にユーザーチェックをこなすことができます。

 * 初回ログイン時
    1. Google Sign-In SDKによってGoogle Id Tokenを取得する
    1. サーバー側でユーザーのリソースにアクセスする場合は、上記に加えてサーバー用のAccessCodeも要求する
    1. 取得したGoogleIdTokenとAccessCodeをサーバーに送信する
        * `curl -H "Authorization: Bearer {google-id-token}" https://example.com/token?accessCode={AccessCode}`
    1. GAE/Fireで`Authorization`ヘッダを検証し、問題なければ生成したFirebase Custom Auth用のトークンを返却する
        * 必要であればユーザーのOAuth2トークンも取得して、RefreshTokenをDatastoreに保存する 
    1. トークンを用いてFirebaseにログインする
 * 認証以後の通信
    1. Firebaseから`getToken()`相当のメソッドで通信トークンを得る
    1. 通信トークンを用いてAPIを叩く
        * `curl -H "Authorization: Bearer {firebase-token}" https://example.com/users/me`
    1. GAE/Fireで`Authorization`ヘッダを検証し、問題なければ処理を継続する

# 最後に

何か不具合や問題があったらissueを書いてくれるとありがたいです。