今回のお話
Firebaseのサービスだけを使ってOAuth2認証をして、front(Angular)で扱えるAccesstokenを取得しよう!というお話。それに付随してEVEOnlineの話。EVEOnlineっていう優れた経済システムを持つサンドボックス型MMOであるが、このゲームSwaggerによる3rd party アプリの作成がサポートされている。
で、これの利用のためにはOAuth2による認可のやり取りが必要なんですが、このご時世、自分でサーバー建てるのもだるいなぁ。ということで、いっちょ、全ての機能をFirebase上で実装するか!というのが今回の記事の概要です。EVEOnline自体は知らなくても、OAuth2認証を利用するアプリをFirebase上で構築しよう!という際に有効な手法であると考えておりますので興味の有る方は引き続き読んでいただけると幸いです。
ちなみにコードはここに。今回はCloud Funcitonsに利用するコードの話が中心になるが、需要があったらFirebaseの利用方法も合わせて、Zennあたりで本にしてみようかなと考え中なので反応があると嬉しいです。
https://github.com/mogeta/eve_auth_cloud_functions
利用技術
- Go
- Cloud Functionでアクセストークン周りと認証制御利用
- Angular
- サードパーティアプリのフロント
- Firebase Hosting
- コンテンツ配信に
- Firebase Cloud Function
- OAuth2の認可取得、新規ユーザー登録、トークンのリフレッシュに利用。
- Firestore
- アクセストークンの保持に利用。
- Firebase Auth
- ユーザー認証、管理。
この構造に至るまでの検討
OAuth2を扱うにあたって、Client Secretを一般のユーザーから見えないところにおいておきたいよね。という要望が生まれる。これを実現するためには一般的に「サーバーサイド」と呼ばれるような領域に格納しておく必要があるが、これはGoogle Cloud Functionsで実現できるだろうと踏んだ。となると、データの格納はFirestoreになるし、どうせならHostingもしてしまおう。となった次第。
導線
- Firebase上に自分がユーザー登録されているか確認。されていなければCloudfunctionへ
- EVEOnlineにアクセストークンを要求するためのURLを生成。
- ユーザーがそのURLにアクセスし、アプリを許諾。auth codeを取得し戻る
- auth codeとclient secretをEVEOnlineへ送信、問題なければAccesstokenを取得
- accesstokenの検証を行う。
- accesstokenが正規に発行されたものだという検証が終わったらFirebase authにユーザー登録を行う。
- 新規登録が終わったらカスタムトークンを発行し、Hostingしてるフロント側へリダイレクト。
- ユーザーがAPIを利用可能な状態となる。
ユーザー管理をAuthでやりたい
ユーザーの認証自体はEVEOnlineでできるにしても、ユーザーの管理とかしたくねー。FirebaseのAuthに丸投げできる方法はないのか?→ある。
これがカスタムトークンの話。uidを独自に定義して、それに対応したFirebase authのアクセストークンを発行することで、独自の認証をつかっていてもFirebase Authに紐付けることができるようになる。
Cloud Functionsとstate
OAuth2のCSRF対策のためにstateにユーザー毎ランダムな文字列を渡して検証するのが望ましいが、Cloud Functionsではcookieに特別な値だけが使えるようになっています。
アクセストークンの有効性をチェック
整合性のチェックの仕方自体はドキュメントがある。これは別にEVEOnlineに特化してるわけではなく、OAuth2ならチェックしましょうという感じのもの。
公開鍵の情報を取得できるURLが有るので、これを使ってJWTの検証を行う。
コードとしては以下のような形。
check するための引数が関数になっているのは暗号の種類を判断してからチェックを開始するからでここはなるほど。となったポイント。
EVEOnlineから帰ってくるアクセストークンを利用して、Firease Authにユーザーを登録する
EVEOnline側で認証を済ませて戻ってくると、AccessTokenが得られる(JWT)。JWTを分解したパラメータからユーザーのUIDを作成する。こうすることで、認証そのものはEVEOnline側に任せつつも、ユーザー管理自体はFirebaseの機能を使うことができるようになる(代償として、2つのアクセストークンが飛び交うことになるので混同しないように注意)
更にいうと、AdminSDKの利用をすることになる。ここについてはまた後日記載する。
ESIはSwaggerなのでクライアントのAPI周りを自動生成できる。
ng-swagger-gen -i <path_to_swagger_json>
生成したServiceに対しhttp-interceptorを利用して渡す。
まとめ
Firebase上だけでOAuth2認証を利用したWebアプリはとりあえず作れそう。Firebaseの仕様を理解してさえいれば大きなつまづきはないと思う。Firebaseそのものにはほとんど費用はかかっていないが、Cloud Functionsのコードを保管するのに数円の料金がかかっている。ユーザー登録とAPIを叩く環境は出来たのでここからどういうアプリを作ろうかなーというのが実は大きな課題だったりする。
参考
- https://jwt.io/#debugger-io
- https://github.com/douglasmakey/oauth2-example
0 件のコメント :
コメントを投稿