最近業務で以下のような構成のAPIサーバー構築をしたので備忘録的に書きました。今回はサーバー編になります。クライアント編(iOSでの実装)はあとで書こうと思っています。
- 全体のざっくり構成図
今回サーバー側でやりたいことは、あるリクエストが信頼できるユーザからのリクエストなのかどうかを検証することです。
全体の流れは以下のような感じになりました。
- クライアント側でFirebaseAuth SDKを使って、Firebaseに自分のトークンを作成してもらいます。(今回は事前にAnonymousユーザを作成してクライアントに割り当てています。)
- FirebaseではJWTTokenを作成してレスポンスします。FirebaseAuthでは特に指定がないとJWTトークンの暗号化アルゴリズムはRS256を使っているようです。
- クライアント側で認証APIに対してリクエストします。このとき、②のトークンを
Authorization: Bearer {{JWTトークン}}
のような形式でリクエストヘッダーに付与します。Authorization
というキー名で認可に使うためのトークンを付与することはOAuthに限らず利用して良さそうです。(RFC 6750) - 認証APIではヘッダーからトークンを取ってきて、Firebase Admin SDKを利用してそのトークンが正しいトークンであるのか検証します。
- 検証結果がFirebaseから返ってきたら、正しいトークンの場合は
200
を返して、間違っている場合は401
を返します。
この Authorization: Bearer
を使ったトークン認証・認可に関してはこちらの記事がわかりやすかったです。
実装
- まず認証に使うためのパッケージは
firebase.google.com/go
になります。僕の環境の場合、こちらのパッケージを手元のダウンロードしてくるときに以下のようなエラーが出力されました。
cloud.google.com/go/storage
と cloud.google.com/go/firestore
が関係しているエラーだった。僕の環境ではこれらのパッケージが古かったようで、再度インストールすることで、 firebase.google.com/go
のインストールにも成功しました。
2. 次に firebase.google.com/go
を使って、ヘッダーのトークンを検証したコードが以下になります。
トークンの検証には Bearer:
という文字列を含めてしまうと、 invalid
トークンになってしまうので、最初に削ってから VerifyIDToken
しましょう。 VerifyIDToken
の戻り値は以下のような構造体が返ってきます。ちなみに、トークンの有効期限は発行から1時間までが有効期限になります。次の記事で書こうと思っていますが、リクエストの度にトークンを更新するのが良さそうだと思っています。
まとめ
今回はFirebaseAdmin SDKを使ってクライアントから送信されたFirebaseAuthトークンの検証をしました。
たったのこれだけで安全な認証・認可の仕組みを作成できるのでとても楽です。Firebaseは基本的に無料で利用できるので、手軽に認証・認可の仕組みを作れるのでおすすめです。
次回はクライアント側でトークンを発行している部分の実装(iOSですが)を書きたいと思います。