Hasura + Firebaseで実践GraphQL入門
こんにちは @glassmonekeyです。zenn 初記事です。
この記事はGraphQL アドベントカレンダー4 日目の記事です。
普段は趣味でFlutter
でのアプリ開発に勤しんでいます。
今回は初心者ながらもその際の個人開発のバックエンドに Hasura
を活用してとても便利だったのでその紹介の記事となります。
大部分を認証付きGraphQL APIサーバーを爆速で立てる。 Hasura + Firebase Authenticationを参考にさせていただきました。
この場を借りてお礼申し上げます。
Hasura
+Firebase Authentication
の組み合わせで認証付き GraphQL エンドポイントが執筆時点だと、より簡単に作れるようになってたのではまるポイント共々合わせて記事にしてみました。
また、Flutter
との連携に関してはFlutter から Hasura + Firebaseで作ったGraphQL APIを活用するを参照ください。
Hasuraとは
Postgress から簡単に GraphQL エンドポイントを作成できるサービスです。
マイグレーション管理なども付属の CLI を使えば簡単にできるので、私のように Postgress に詳しくなくても扱えるのが学習コスト低めでとてもよいです。
GraphQL
のクエリ自体も GUI 操作で組み立てられるので、GraphQL
の入門にもオススメしたいサービスとなっております。
ちなみに無料版だと Heroku にデータベースを用意する形になります。もちろん他にホスティングしているものがあるならそれを使うこともできます。
無料だとリージョンで日本を選べないので、プロダクション環境では課金して日本リージョンで動かすなどは検討したほうが良いでしょう。
認証機能について
認証機能は Postgress の行アクセス制限などを使ってたりするので、情報を見つけやすいことも魅力な点です。
アクセス方法は大きく以下の2点が設定できます。
- 管理トークンによるアクセス
- JWT によるアクセス
- WEB HOOKにによるアクセス
- 未認証アクセス
また、データに対するアクセスはロールによる制御がされています。
管理トークンでアクセスしたときは admin ロール(全データの CRUD 操作が可能なロール)のよるアクセスが設定され、
JWT によるアクセス時は JWT のクレームで設定した値に応じてロールを設定できます。
詳細は公式のRoles & Session variablesをみると良いでしょう。
以下は admin ロールと user ロールを予め作った例になります。
user は partical アクセスとなっており、部分的にしか CRUD 操作できないといった設定が可能です。
Firebase
との連携の際は FirebaseAuthentication
から uid を X-Hasura-User-Id
ヘッダーとして簡単にもらうことができるので、
uid カラムを用意してそこに一致する場合のみ操作可能にする権限設定が可能です。
Hasura と Firebase との連携
概要
今回扱う認証は Firebase Authentication
の JWT を Hasura
の認証に利用する方式となります。
2021 年 9 月時点だと heroku を意識しなくてよくなってる点や、function を用意しなくてもよくなってる点が上記記事に加えて大きな変更点として挙げられます。
Hasuraのセットアップ
-
プロジェクトを作ります。
最初は無料版でいいでしょう。無料版だと日本リージョンで作れないなど注意が必要です。
-
コンソールを開きます
3. データベースの項目に移動します。
- heroku からの連携をすると終わりです
アクセス制限に関してはデフォルトで HASURA_GRAPHQL_ADMIN_SECRET
が設定されているはずなので
一旦は気にしなくても大丈夫です。 Env vars のところから確認できます。
これが漏れてしまうと、全テーブルに無差別でアクセスができる状態になっています。
動作確認
この段階でためしにデータを入れて GraphQL のクエリをためしてみましょう。
GUI 操作で create テーブルと insert なども可能ですがここでは割愛します。
テーブル追加とデータ追加すると Exploer から GUI 操作でクエリ操作を検証できます。
このコンソール画面では管理トークンを使った admin ロールで行います。
ユーザー権限の動作確認は x-hasura-role
などを設定して擬似的にそのユーザーの権限になることもできます。 詳細はAccess control basicsに記載されています。
Firebaseのセットアップ
認証基盤としての FirebaseAuthentication のセットアップを行います。
今回は FirebaseAuthentication のみ使います。認証基盤は好きなのをご利用ください。
カスタムクレームのアップロード
Hasura
にはcustom claimsという、
jwt の claims からいい感じに認証データを読み取ってくれるマッピングを設定があります。
FirebaseのJWTトークンの構成を確認する。
ちなみに Firebase Authentication
の JWT をデコードすると、clams 以下は執筆時点以下のような構成です。
google sigin in してる状態なので sign_in_provider
が google.com になっています。
トークンの詳細はVerify ID Tokensにも記載があるので、確認するといいでしょう。
{
picture: プロフィールの画像パス,
firebase: {
identities: {
google.com: [
略
],
email: [
略
]
},
sign_in_provider: google.com
},
user_id: FirebaseAuthentication上のUID,
aud: firebaseプロジェクト名,
exp: 1630883599,
iat: 1630879999,
iss: "https://securetoken.google.com/firebaseプロジェクト名",
sub: FirebaseAuthentication上のUID,,
name: 名前,
email: メールアドレス,
email_verified: true,
auth_time: 1630879999
}
HASURA側にアップロードする
- HASURA_EnvVars から
New Env Var
からHASURA_GRAPHQL_JWT_SECRET
を追加します。
- 以下のような内容を記述して Add します。
※ プロジェクト名となっているところは各自Firebase
のプロジェクト名に読み替えてください
json path でFirebase
の設定からマッピングしてくれるclaims_map
のところが肝です。
詳細は公式をご確認ください。
{
"type": "RS256",
"issuer": "https://securetoken.google.com/プロジェクト名",
"jwk_url": "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com",
"audience": "プロジェクト名",
"claims_map": {
"x-hasura-user-id": {
"path": "$.user_id"
},
"x-hasura-default-role": "user",
"x-hasura-allowed-roles": [
"user"
]
}
}
本来 Hasura
の jwt の仕様としては以下のようにしないといけないことを
Firebase
のデフォルトのクレームのまま Hasura の認証に通すことができるようになります。
なお、上記の JWT のトークンで認証する場合は一律 user 権限としてしています。
もう少し凝ったロール構成にしたい場合は Firebase 側の JWT にカスタムクレームを付与するなどしないといけません。
筆者はそこに関して検証ができていませんが、おそらくFirebaseのカスタムクレーム
の記事を参考にすると良さそうです。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022,
"hasura": {
"claims": {
"x-hasura-allowed-roles": ["editor","user", "mod"],
"x-hasura-default-role": "user",
"x-hasura-user-id": "1234567890",
"x-hasura-org-id": "123",
"x-hasura-custom": "custom-value"
}
}
}
Add で追加後、しばらくすると Hasura Env Vars に追加されたら作業は完了になります。
検証
アプリケーション上の動作確認は明日別記事で公開するので、この記事としては割愛させていただきます。
Flutter 側の設定はFlutter から Hasura + Firebaseで作ったGraphQL APIを活用するを参照ください。
おわりに
今回は Firebase
と Hasura
に組み合わせで簡単に認証機能つき GraphQL エンドポイントが作れる点について解説しました。
バックエンドを用意せずに認証機能が使えるのはとても便利ですね。マイグレーション機能も内包してる点も非常に素敵です。
GraphQL
と Postgress
の両方の初心者の自分がそこまでつまずかずに環境構築・開発ができているのは本当に良いです。
アプリケーション開発の視点でも GraphQL
のおかげで型生成も容易なので、DB のデータをフロントから型安全に触ることができているのは不思議な感覚です。
ぜひみなさんも遊んでみてください。
Flutter や GraphQL のことをたまにつぶやいてたりするので、もしよかったら@glassmonekeyをフォローしていただけると喜びます。
Discussion