Windows 11でPostgRESTを動かしてみる
はじめに
Windows 11でPostgRESTのチュートリアルを試してみました。
PostgRESTとは
PostgRESTとは、PostgreSQLデータベースを操作するRESTful APIを提供するWebサーバーです。ざっくりまとめると、以下の3ステップでデータベースにアクセスできるAPIが生成されます。
- PostgreSQLデータベースの実行環境を用意
- PostgRESTの設定ファイルにデータベースの接続先等を記述
- PostgRESTを起動
今回の実行環境
- OSはWindows 11
- PostgreSQL 14をインストール済み
- Docker Desktopをインストール済み
- WSL2をインストール済み
- Git Bashをインストール済み
手順(Tutorial 0)
公式ドキュメントのTutorial 0 - Get it Runningの手順に沿って実施していきます。
PostgreSQLを動かすDockerコンテナを作成
Windows PowerShellなどのターミナルで、以下のコマンドを実行し、PostgreSQL入りのDockerコンテナを作成します。
docker run --name tutorial -p 5433:5432 -e POSTGRES_PASSWORD=password -d postgres
Docker Desktopのコンテナ一覧にこんな感じで生成されていれば良いです。
システム環境変数のPathにPostgreSQLのパスを追加
Windowsの環境変数の設定画面を開く
システム環境変数のPathに、あらかじめWindowsにインストールしておいたPostgreSQLのbinフォルダのパスを追加
(C:\Program Files\PostgreSQL\14\bin とかになると思います)
PostgRESTをダウンロード
PostgRESTのGitHubリポジトリから、最新のPostgRESTをダウンロードします。
(今回は postgrest-v10.1.1-windows.x64.zip にします)
ダウンロードしたzipファイルを解凍しておいてください。
Dockerコンテナ内のPostgreSQLにスキーマを作成
先程の手順で作成したDockerコンテナに接続し、今回使用するスキーマを作成していきます。
まずは以下のコマンドでコンテナに接続します。
docker container exec -it tutorial /bin/bash
コンテナに接続できたら、続けてその中のPostgreSQLに接続します。
psql -U postgres
スキーマを作成します。
create schema api;
todosテーブルを作成します。
create table api.todos (
id serial primary key,
done boolean not null default false,
task text not null,
due timestamptz
);
todosテーブルにデータを追加します。
insert into api.todos (task) values
('finish tutorial 0'), ('pat self on back');
web_anonロールを作成します。
create role web_anon nologin;
web_anonロールにapiスキーマへのusage権限を追加します。
grant usage on schema api to web_anon;
web_anonロールにtodosテーブルへのselect権限を追加します。
grant select on api.todos to web_anon;
PostgRESTからのログインに使用するauthenticatorロールを作成し、web_anonロールと同様の権限を付与します。
create role authenticator noinherit login password 'password';
grant web_anon to authenticator;
これでスキーマの準備は一旦完了です。
PostgRESTの設定ファイルを作成
先程ダウンロードしたPostgRESTのzipファイルを解凍すると、中にpostgrest.exeが入っていると思います。
そのフォルダと同じ場所に、tutorial.confを作成します。
ファイルの中身は以下のようにしてください。
db-uri = "postgres://authenticator:password@localhost:5433/postgres"
db-schemas = "api"
db-anon-role = "web_anon"
PostgRESTを起動
Windows PowerShellでpostgrest.exeが置いてあるフォルダに移動し、exeを起動します。
.\postgrest.exe tutorial.conf
こんな内容の起動ログが出力されたら成功です。
30/Dec/2022:22:02:50 +0900: Attempting to connect to the database...
30/Dec/2022:22:02:50 +0900: Connection successful
30/Dec/2022:22:02:50 +0900: Listening on port 3000
30/Dec/2022:22:02:50 +0900: Listening for notifications on the pgrst channel
30/Dec/2022:22:02:50 +0900: Config reloaded
30/Dec/2022:22:02:50 +0900: Schema cache loaded
この状態で http://localhost:3000/todos にアクセスすると、以下のようなjsonデータが出力されると思います。
[
{
"id": 1,
"done": false,
"task": "finish tutorial 0",
"due": null
},
{
"id": 2,
"done": false,
"task": "pat self on back",
"due": null
}
]
ここまでで、公式ドキュメントのTutorial 0 - Get it Runningの実施は完了です。
手順(Tutorial 1)
ここからは、Tutorial 1 - The Golden Keyの内容に沿って進めていきます。
todosテーブルを更新するためのロールを作成
コンテナ内のPostgreSQLに接続
docker container exec -it tutorial /bin/bash
psql -U postgres
todo_userロールを作成します。
create role todo_user nologin;
grant todo_user to authenticator;
todosテーブルで使用される全ての権限をtodo_userに付与します。
grant usage on schema api to todo_user;
grant all on api.todos to todo_user;
grant usage, select on sequence api.todos_id_seq to todo_user;
シークレットキーを生成
Git Bashを起動し、以下のコマンドを実行します。
export LC_CTYPE=C
< /dev/urandom tr -dc A-Za-z0-9 | head -c32
(※先頭の < を省略しないように注意)
出力された32文字の文字列をコピーしておきます。
次に、tutorial.confをエディタで開き、以下の1行を追記します。
jwt-secret = "ここに生成したシークレットキー"
追記後、postgrest.exeを再起動しておいてください。
シークレットキーからアクセストークンを生成
JSON Web Tokens - jwt.ioにアクセスし、PAYLOADとVERIFY SIGNATUREを以下のように設定してください。
設定後、左側のEncodedに表示された文字列をコピーしておいてください。
これがAPIのアクセストークンになります。
API経由でtodoテーブルにレコードを追加してみる
Git Bashを起動し、以下のコマンドを実行していきます。
直前の手順でコピーしたトークンを変数に設定します。
export TOKEN=ここにトークンを貼り付け
API経由でtodosテーブルにレコードを登録してみます。
curl http://localhost:3000/todos -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"task": "learn how to auth"}'
todosテーブルの全レコードのdoneカラムの値をtrueに更新する処理を実行してみます。
curl http://localhost:3000/todos -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"done": true}'
todosテーブルのレコードを取得してみます。
curl http://localhost:3000/todos
こんなjsonデータが出力されていれば成功です。
[{"id":1,"done":true,"task":"finish tutorial 0","due":null},
{"id":2,"done":true,"task":"pat self on back","due":null},
{"id":3,"done":true,"task":"learn how to auth","due":null}]
トークンに有効期限を持たせてみる
5分後に有効期限切れになるトークンを作成してみます。
まずはDockerのPostgreSQLに接続し、以下のSQLを実行します。
select extract(epoch from now() + '5 minutes'::interval) :: integer;
実行結果の数値をコピーしておいてください。
JSON Web Tokens - jwt.ioにアクセスし、PAYLOADを以下のように編集します。
VERIFY SIGNATUREには前の手順と同様の文字列を設定しておきます。
その後、左側のEncodedに表示された文字列をコピーしておいてください。
次に、Git Bashで、以下のコマンドを実行していきます。
export NEW_TOKEN=ここにトークンを貼り付け
todosテーブルの中身を取得してみます。
curl http://localhost:3000/todos \
-H "Authorization: Bearer $NEW_TOKEN"
select extract~ のSQLを実行してから5分以内であれば、todosテーブルの中身が表示されます。
5分以上経過した状態で上記のAPIを呼び出すと、以下のレスポンスが返ってきます。
{"code":"PGRST301","details":null,"hint":null,"message":"JWT expired"}
トークンを即時失効させてみる(特定のユーザーからのアクセスを拒否する)
JSON Web Tokens - jwt.ioにアクセスし、PAYLOADを以下のように編集します。
VERIFY SIGNATUREには前の手順と同様の文字列を設定しておきます。
その後、左側のEncodedに表示された文字列をコピーしておいてください。
DockerのPostgreSQLに接続し、以下のSQLを実行してユーザー認証用のスキーマと関数を作成します。
create schema auth;
grant usage on schema auth to web_anon, todo_user;
create or replace function auth.check_token() returns void
language plpgsql
as $$
begin
if current_setting('request.jwt.claims', true)::json->>'email' =
'disgruntled@mycompany.com' then
raise insufficient_privilege
using hint = 'Nope, we are on to you';
end if;
end
$$;
エディタでtutorial.confを開き、以下の行を追記します。
db-pre-request = "auth.check_token"
追加後、postgrestを再起動します。
Git Bashで、以下のコマンドを実行してtodosテーブルを更新してみます。
curl http://localhost:3000/todos -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"done": true}'
これは問題なく実行されます。
次に、アクセス拒否したいメールアドレス(disgruntled@mycompany.com)を含むトークンを使ってAPIにアクセスしてみます。
curl http://localhost:3000/todos -X PATCH \
-H "Authorization: Bearer $WAYWARD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task": "AAAHHHH!", "done": false}'
以下のレスポンスが返ってきます。また、todosテーブルのレコードは更新されません。
{"code":"42501","details":null,"hint":"Nope, we are on to you","message":"insufficient_privilege"}
これで、公式ドキュメントのTutorial 1 - The Golden Keyの実施も完了です。
おわりに
Windows 11でPostgRESTを動かしてみました。
この記事ではチュートリアルの内容しか紹介していませんので、詳細な使い方については公式ドキュメントをご参照ください。
Discussion