Hasuraで遊んでみる ~その2~

2021.09.27

Hi there,

前回の記事の続きです。

テーブル操作の権限をつける

特定の条件に基づいてテーブルのクエリを制限することが可能となっています。

特定のユーザーにはアイテムを追加できないようにするとか、削除できないようにする などですね。

今回はitemsテーブルで試してみます。

itemsテーブルの中のPermissionsタブをクリックし、Roleを追加していくことで権限の設定ができるようになります。

例えば、group1 の roleならば特定のカテゴリの追加しかできない 権限をつけるならば、

insert権限の編集(鉛筆)アイコンをクリックします。 すると、下のセクションが開き、カスタムチェックを構成して列を許可できます。

  • custom checkの箇所に {"category_id":{"_eq":"1"}} と入力します。
  • Column insert permissionsの箇所で published,price,name,createdAt,updatedAt を選択します
  • Column presetsの箇所にcategory_id , static, 1 と入力します。

最後にSave Permissionsをクリックして設定完了です。

参照や更新も条件をつけたいのであれば同じように設定していきましょう。

認証によるHasura GraphQLエンジンの保護

商品の登録や削除などをするアプリを想定した場合、認証は必須になります。

Hasura GraphQLエンジンを保護するために、今回はauth0を使用してみます。

基本的な考え方は、ユーザーが Auth0 で認証すると、クライアントアプリがトークンを受け取り、 そのトークンを GraphQL リクエストの Authorization ヘッダーに含んで送信されます。Hasura GraphQL エンジンは、トークンが有効かどうかを確認し、ユーザーが適切なクエリを実行できるようにします。

Auth0にアプリケーションを作成

Auth0にログインし、アプリケーションを作成します。WebアプリだったりSPAだったりは考えているフロントエンドアプリによって変わります。

作成に関しては以下を参照しましょう。

JWT claimのカスタマイズ

Hasuraに呼び出し元の役割を通知するためにカスタムする必要があります。

Auth0ではRulesかActionsを使って認証フローをカスタマイズすることが可能です。

今回はActionsを使ってみます。

呼び出し元が実行できることと実行できないことをHasuraに伝えるためにclaimを追加します。

せっかくなので先ほどつけた権限(group1)で実行するようにしていきましょう。

以下のコードをカスタムアクションに追加し、デプロイします。

exports.onExecutePostLogin = async (event, api) => {
  if(event.client.client_id !== "<<作成したアプリケーションのclient id>>") {
    return;
  }

  const namespace = 'https://hasura.io/jwt/claims"';
  if (event.authorization) {
    const claims = {
      'x-hasura-default-role': 'group1',
      'x-hasura-allowed-roles': ['group1','group2','group3'],
      'x-hasura-user-id': event.user.user_id
    }
    api.idToken.setCustomClaim(namespace, claims);
  }
};

hasuraのJWT認証に関しては以下のページが参考になりました。

デプロイ後、作成したactionをLoginフローに組み込みます。

Auth0アプリケーションにHasuraを接続する

ProviderをAuth0にし、Domain NameにAuth0のテナントドメイン名を入力してGenerate Configボタンを押します。

生成された設定情報はコピーしておきます。

Hasura CloudのプロジェクトページにあるEnv varsをクリックします。

HASURA_GRAPHQL_JWT_SECRETという名前で先ほどコピーした設定情報を値ボックスに貼り付けます。

これでHasura GraphQL エンジンがAuth0を使用して保護されるようになります。

トークンを使ってGraphQLクエリを実行

Auth0を使用して認証するように設定したので、Auth0からトークンを取得しGraphQLクエリを実行してみます。

Auth0で設定した時にgroup1というRoleをつけたので、その権限の操作しかできないはずです。

先ほど設定した 特定のカテゴリ(category_id=1)の追加しかできない の他に、特定のカテゴリ(category_id=1)しか検索できない も追加しておきました。

※ トークンは、Auth0のアプリにログインして取得したり、APIから取得できます。

トークンを取得したら、HasuraのダッシュボードのAPIの画面でセットします。

デフォルトで付いているRequest Headerのx-hasura-admin-secretは無効にしておきます。

Authorization というKeyを追加し、

Value にBearer <<Auth0から取得したトークン>> をセットしてGraphQLクエリを実行してみましょう。

特定のカテゴリ(category_id=1)しか検索できないという権限がついているため、結果はcategory_id=1のデータのみが返ってきていますね。

category_id=3のものだけを検索したら結果は空で返ってきます。

最後に

テーブル操作に権限をつけ、Auth0で認証してHasura GraphQL エンジンを保護してみました。

アプリケーションごとに ログインユーザーにしか参照できない、管理者にしか追加できない、自分のデータしか参照、更新ができない等 があるかと思いますが、Hasuraでも柔軟に対応できることがわかりました。

参考

hasuraのチュートリアル