つくる:認証完備
新しいことは出てきません
この回では、新しい知識は 1 つも出てきません。第7章で書いたものを 1 つにまとめて、登録からログイン、出品、編集までを通します。
通しで見ると流れが分かる
プレーンテキスト
1. POST /register 名前とパスワードを送る → 利用者ができる
2. POST /login 名前とパスワードを送る → トークンをもらう
3. POST /items トークンを添えて出品 → 自分の商品として登録される
4. PUT /items/:id トークンを添えて編集 → 自分のものだけ通る1 と 2 は似ていますが、役割が違います。登録は利用者を作る、ログインはその人だと確かめて引換券を渡すです。
3つのコードの住み分け
第7章で、断り方が 3 つに分かれました。
| コード | いつ | 直せるか |
|---|---|---|
| 401 | 誰だか分からない | ログインすれば通る |
| 403 | 誰かは分かるが権限が無い | ログインし直しても通らない |
| 404 | 対象が存在しない | 対象を変えれば通る |
見る順番は 401 → 404 → 403 です。認証はミドルウェアで先に済み、その後で存在を見て、最後に権限を見ます。
守るものと開けておくもの
すべてを守ればよいわけではありません。
JavaScript
app.get("/items", ...); // 誰でも見られる
app.post("/items", requireAuth, ...); // 出品はログイン必須
app.put("/items/:id", requireAuth, ...); // さらに本人だけ商品を見るのは誰でもできて、出品はログインした人、編集は出品者だけ。段階的に狭めていくのが自然な設計です。
ここまでに手に入れたもの
| 何を | どのレッスンで |
|---|---|
| 認証と認可を分ける | 認証と認可 |
| 元に戻せない形で保存する | パスワードハッシュ |
| 引換券を発行する | ログインとトークン |
| ミドルウェアで止める | 保護ルート |
| 出品者と突き合わせる | 本人のものだけ |
手を動かす
演習では、登録からログイン、出品、編集までを備えた API を組み立てます。第7章の総仕上げです。
要件
POST /loginはハッシュを照合し、通れば{"token":"token-<名前>"}を 200 で返す(失敗は 401)POST /itemsはrequireAuthを掛け、req.user.nameを出品者として 201 で返すPUT /items/:idは 404 → 403 の順に確かめ、通れば更新後の商品を 200 で返す
入出力例
request("POST", "/login", {"name":"田中","password":"himitsu"}) → "200 {"token":"token-田中"}"
request("POST", "/login", {"name":"田中","password":"chigau"}) → "401 {"error":"名前かパスワードが違います"}"
request("POST", "/login", {"name":"佐藤","password":"himitsu"}) → "401 {"error":"名前かパスワードが違います"}"
request("POST", "/items", {"name":"木製のスツール"}, "token-田中") → "201 {"id":2,"name":"木製のスツール","owner":"田中"}"
request("POST", "/items", {"name":"木製のスツール"}) → "401 {"error":"ログインしてください"}"
request("PUT", "/items/1", {"name":"のっとり"}, "token-田中") → "403 {"error":"この商品は編集できません"}"
request("PUT", "/items/1", {"name":"革のスニーカー"}, "token-鈴木") → "200 {"id":1,"name":"革のスニーカー","owner":"鈴木"}"
request("PUT", "/items/999", {"name":"x"}, "token-田中") → "404 {"error":"商品が見つかりません"}"ヒント
編集 ゆめさく編集部