鍵のない API は誰にでも開いている
API の認証は、リクエストを送ってきたのが誰かを確かめる仕組みです。鍵のない API は、アドレスを知っている人なら誰でも、読み、書き換え、消せます。
図書館の API を公開するなら、誰が何回まで使えるかを決める必要があります。キー、トークン、回数の制限の3つを学びます。
このレッスンのゴール
メモ
キー、トークン、回数の制限で、API を守る方法を選べる。
重要な言葉
| ことば | いみ |
|---|---|
| 認証 | 送ってきたのが誰かを確かめること |
| API キー | アプリを見分ける、長い秘密の文字列 |
| ベアラートークン | 持っている人を本人とみなす、期限付きの文字列 |
| ハッシュ | 元に戻せない、指紋のような文字列 |
| レート制限 | 一定の時間に使える回数の上限 |
| 429 | 回数の上限を超えたことを表す番号 |
学生が入力するセルは、このプレビューでは空白です。
キーはアプリを、トークンは利用者を見分ける
API キーは、アプリに渡す長い秘密の文字列です。リクエストのヘッダーに付けて送ります。
ベアラートークンは、ログインした利用者に渡す文字列で、期限があります。Authorization: Bearer に続けて送ります。持っている人を本人とみなすので、他人に見せてはいけません。
例: キーとトークンの違い
| 違い | API キー | ベアラートークン |
|---|---|---|
| 見分けるもの | アプリ | ログインした利用者 |
| 期限 | 長い、または無期限 | 短い。数分から数時間 |
| 送り方 | X-API-Key ヘッダー | Authorization ヘッダー |
| 漏れたとき | キーを作り直す | 期限を待つか、取り消す |
学生が入力するセルは、このプレビューでは空白です。
例: 守るときの3つの番号
| 番号 | 意味 | 場面 |
|---|---|---|
| 401 | 名乗っていない、または鍵が間違い | キーを付け忘れた |
| 403 | 本人だが、許されていない | 他人の貸出を読もうとした |
| 429 | 回数の上限を超えた | 短い間に送りすぎた |
学生が入力するセルは、このプレビューでは空白です。
このラボの API は鍵なしで通る
このラボの API には、キーもトークンもありません。アドレスを知っていれば、誰でも読めて書けます。ラボは自分専用なので、それでかまいません。
本物のサービスでは許されません。鍵なしで通ることと、何回送っても止まらないことを、確かめます。
psql にパスワードを渡す
export PGPASSWORD=shopここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
本の表を作り直す
psql -h db -U shop -c "drop table if exists books; create table books (id serial primary key, title text not null, author text not null, year int not null, copies int not null default 1); insert into books (title, author, year, copies) values ('Networks in Practice', 'Mori', 2019, 3), ('Learning SQL', 'Tanaka', 2021, 2), ('Web Design Basics', 'Suzuki', 2018, 0), ('Intro to APIs', 'Kato', 2022, 5); notify pgrst, 'reload schema'"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
鍵なしで読む
curl -s -o /dev/null -w "%{http_code}\n" "http://api:3000/books"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
続けて5回送る
curl -s -o /dev/null -w "%{http_code}\n" "http://api:3000/books?limit=[1-5]"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
サービスはキーそのものを保存しない
保存したキーが盗まれると、誰でもそのアプリになりすませます。そこで、サービスはキーのハッシュだけを保存します。
届いたキーのハッシュを計算して、保存したものと比べます。ハッシュからキーは戻せません。次の Run で、1文字違うだけで全く違うハッシュになることを見ます。
キーのハッシュを計算する
printf 'lib-key-2026' | sha256sumここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
1文字違うキーのハッシュ
printf 'lib-key-2027' | sha256sumここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
練習: トークンの期限を調べる
issued_at = 1000 # トークンを出した時刻(秒)
lifetime = 900 # 有効な長さ(秒)
now = 1800 # 今の時刻(秒)
if now < issued_at + lifetime:
print("有効です")
else:
print("期限切れです")
# 練習: now を 1900 に変えて、もう一度 Run しましょう。
レート制限は使いすぎを止める
レート制限は、一定の時間に送れるリクエストの数に、上限を付けることです。上限を超えたら、429 を返します。
代表的な方式は、トークンバケツです。バケツにチケットが入っていて、リクエスト1回で1枚減ります。時間がたつと、決まった割合で補充され、満杯より増えません。空なら 429 です。
例: バケツの動き(上限3枚、2秒に1枚)
| 時刻(秒) | 補充後の枚数 | 結果 | 使った後の枚数 |
|---|---|---|---|
| 0 | 3 | 200 | 2 |
| 0 | 2 | 200 | 1 |
| 1 | 1.5 | 200 | 0.5 |
| 1 | 0.5 | 429 | 0.5 |
| 2 | 1 | 200 | 0 |
| 2 | 0 | 429 | 0 |
| 4 | 1 | 200 | 0 |
学生が入力するセルは、このプレビューでは空白です。
よくある間違い
注意
API キーをアプリの画面側のコードに書いて配れば、安全だと考えがちです。ブラウザに届いた文字は、誰でも見られます。キーはサーバー側に置き、画面には出しません。