LoginSignup
4
5

More than 5 years have passed since last update.

postgRESTの認証でドはまりしたメモ

Posted at

この記事は

postgreSQLにWebからアクセスするためのAPIを提供するpostgRESTをつかおうとしたときに、認証周りで失敗した話です。

失敗の経緯

  • 提供されているdocker-composeで動かして、とりあえずうまく行っていた
  • そろそろ認証をかけたいなと思ったときに、色々な勘違いにより失敗した。

はじめに

ちょっとした経緯で、またWebアプリを書くことになりました。

データベースに格納されたデータを参照して、意思決定をしたいということで、supersetやらmetabaseを使えばよさそうなんだけれども、ちょっとインタラクションをこだわりたいみたいな話があり、やむなくBootstrapベースでフルスクラッチすることに。
(((要求抽出が進んで、これってMetabaseでよくね?となってきたのですが、それはおいておいて…)))

今回は認証周りで色々ハマったので、忘備録として軽くメモ書きします。

結論を早く知りたい人は、一番下にまとめてあるので、それを参照ください。

環境 (バージョンは割愛 ちょっと古いです)

  • CentOS
  • docker
  • docker-compose
  • postgres (docker container)

やったこと

機能の概要は分かったので、とりあえず公開されているdocker-compose.ymlを少し改変して動作させる

docker-compose.yml
version: '3'
services:
  server:
    image: postgrest/postgrest
    # ports:               #ポート3000は公開せずに別のnginxコンテナでリバースプロキシする
    #  - "3000:3000"
    links:
      - db:db
    environment:
      PGRST_DB_URI: postgres://app_user:password@db:5432/app_db
      PGRST_DB_SCHEMA: public
      PGRST_DB_ANON_ROLE: app_user #In production this role should not be the same as the one used for the connection
    depends_on:
      - db
  db:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: app_db
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD: password
  # Uncomment this if you want to persist the data.
  # volumes:
  #   - "./pgdata:/var/lib/postgresql/data"

このコンテナを立ち上げて、nginxでproxy設定を書いてやると、なるほど、いいじゃないか!
ということで、採用。

認証について知るために、あとからチュートリアルをやる

postgRESTはチュートリアルが2段階で用意されており、Tutorial 0(http://postgrest.org/en/v5.1/tutorials/tut0.html) は主にインストールの話、Tutorial 1は認証の話です。

自分は既にdockerでインストール済なので、Tutorial 1から始めました。

tutorial.conf?

Step 1でユーザを作って、Step 2で秘密鍵を作るのですが、その秘密鍵をtutorial.confに記述せよと。dockerをやっている範囲ではそんなもん書いていないので、ここで一度ハマる。

とはいえ、どうせ環境変数で設定するんだろうとタカをくくり、

docker-compose exec server bash
***# env

とやって環境変数を確認。案の定、PGRST_JWT_SECRETというエントリがあったので、適当なパスワード(password的な)のを登録してdocker-compose up -d serverでサーバを再起動。

まったく認証が動作している気配がない。

JWTの設定をしてもapp_dbの内容が全部参照できてしまう。これはどうしたことか、、、と思案するなかで、ここで初めてTutorial 0に戻る。すると

tutorial.conf
db-uri = "postgres://postgres:mysecretpassword@localhost/postgres"
db-schema = "api"
db-anon-role = "web_anon"

docker-compose.yml では db-anon-role が同じスーパユーザに設定されているために、認証に失敗してAnonymousで入った結果、すべて参照できるようになっていたとわかる。
PGRST_DB_ANON_ROLEを存在しないユーザに設定し、想定通り403が返ってくるようになった。

認証が通らない

ここで、jwt.ioで認証トークンを作成して、curlのヘッダに登録すると、次は401で認証エラーが返ってくるようになった。

良く調べると(というか、ちゃんと書いてあるんだけれど)秘密鍵は32文字以上必要とのこと。

というわけで、

秘密鍵を32文字以上にしたら動くようになった。

まとめ

docker-composeでpostgRESTを動かした後はこの手順で設定すればよい。

  • Anonymous Roleを設定する
    • PGRST_DB_ANON_ROLEをスーパユーザ以外に設定する
    • 接続先のDBにロールを作成し、Anonymous用の権限を付ける
  • 秘密鍵を設定する
    • PGRST_JWT_SECRETの環境変数エントリを設定し、32文字以上の秘密鍵を平文で書く
    • JWT.ioにアクセスし、Payloadに {"role": アクセスしていいユーザ}を設定する
      • 何も考えないとapp_userになるが、スーパユーザはなぁ、と思う人はもう一人別のロールを作って権限設定をする。
    • Signatureの「ここだよ」と書いてあるところに秘密鍵を入力する

ついでに分かったこと

  • postgres/postgres dockerイメージは/etc/postgrest.confを参照している。環境変数でなく、confファイルを直接参照させたい人は、このファイルをホストからコントロールできるようにすればいい
4
5
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
4
5