0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BaaSとしてのSupabase

Supabaseは、単なるクラウドデータベースを提供しているだけではなく、postgRESTなどのバックエンドサービスを提供している。

postgRESTとは

postgRESTは、PostgreSQLのデータベーススキーマを読み取って、自動的にRESTful APIを生成するスタンドアロンのWebサーバーである。これによって、サーバ側でAPIコードを書かなくてもテーブルを追加するだけでエンドポイントが生える。

これは、フロントエンドやモバイル・ノーコードツールなどからデータベースを叩きたいときに有益な仕組みといえる。

postgRESTのイメージ
テーブル: teams (id, name)
      ↓ 自動生成
GET    /rest/v1/teams         → 一覧取得
GET    /rest/v1/teams?id=eq.1 → id=1のみ取得
POST   /rest/v1/teams         → 新規作成
PATCH  /rest/v1/teams?id=eq.1 → 更新
DELETE /rest/v1/teams?id=eq.1 → 削除

クエリパラメータはそのままSQLのWHERE句や演算子に対応し、

GET /rest/v1/talents?select=first_name,last_name,teams(name)&team_id=eq.1

のようにすることで、外部キーをpostgRESTが自動検出し、SQLのJOINを書かなくてもselect=teams(name)の部分のようにネストした形でJOIN結果を取得できる。

ちょっと待って

では、このpostgRESTのwebサーバをanonキーで叩けたら誰でもデータを取れてしまうのか? 

そんなことはない

postgRESTはリクエストのAuthorization: Bearer <JWT>を受け取ると、その中身のroleなどを見てPostgreSQL上でそのロールに切り替えてSQLを実行する。そのロールによってRLSでアクセス制御を設定できる。

RLSとは

RLSはRow Level Securityの略で、文字通り、テーブルに対する「行ごとの」アクセス制御を行う仕組みのこと。普通のDB権限管理では、テーブル単位でのアクセス制御しかできないが、RLSではさらに細かい行単位のポリシーで制御できる。

ポリシーとは

RLSが有効になったテーブルに対して「どの操作を、誰に、どんな条件で許可するか」を定義する個別のルールのこと。RLSが有効になった時点では、全アクセス拒否になっているので、ポリシーでアクセス権を追加していく。

policyの基本構文
create policy "ポリシー名"
  on テーブル名
  for select | insert | update | delete | all   -- どの操作に適用するか
  to ロール名                                     -- 誰に適用するか(authenticated, anon など)
  using (条件式)                                  -- 既存の行を対象にできるかの条件
  with check (条件式);                            -- 書き込む行を許可するかの条件

usingとwith checkの違い

  • using: すでにDBにある行を見る・対象にする条件(SELECT・UPDATE・DELETEで使う)
  • with check: これから書き込もうとしている行の中身が条件を満たすかどうか(INSERT・UPDATEで使う)

バックエンドを自前で用意する場合

BaaSとしての機能を使わず(主にpostgRESTについて)、クラウドデータベースを使用したい場合、RLSの有効化が必須になる。というのも、先述した通り、postgRESTはデフォルトで有効になっておりanonキーで叩けてしまうため、RLSでpostgREST経由のアクセスを拒否する必要がある。このとき、RLSを有効化してポリシーを設定しないことで全拒否が実現できる。
バックエンドからデータベースへのアクセスは、テーブルオーナー権限のキーでアクセスすることでRLSの影響を受けずにデータを取れる。

まとめ

  • PostgRESTは、DBスキーマからRESTful APIを自動生成する仕組みで、バックエンドを自前で書かなくてもフロントエンド・モバイル・ノーコードツールなどから直接DBを叩けるようにするための仕組み
  • ただしPostgRESTはデフォルトで有効になっており、anonキーだけでもリクエスト自体は届いてしまう。それでも安全なのは、JWTの中身に応じてPostgreSQL側のロールが切り替わり、RLSによって行単位でアクセスが絞られるため
  • RLSは有効化した時点でデフォルト全拒否となり、using(読む/対象にする条件)とwith check(書き込む内容の条件)を持つポリシーを追加することで、必要な範囲だけアクセスを許可していく
  • PostgRESTを使わず、自前のバックエンドから直接DBに接続する構成を取る場合でも、PostgREST自体は有効なまま公開され続けているため、使用の有無に関係なく、RLSを有効化してポリシーを設定しないことで、この経路を明示的に塞いでおく必要がある
  • 一方バックエンドは、テーブルオーナー権限(postgresロールなど)でDBに直接接続することで、RLSの制約を受けずにデータを自由に操作できる。つまり「PostgREST経由(anon/authenticated)は全拒否、バックエンド直接接続(postgres)はRLS対象外でフルアクセス」という2系統のアクセス経路を明確に分離するのが、この構成の肝である
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?