本人のものだけ
ログインしていれば何でもできる、ではない
前のレッスンで、ログインした人だけが出品できるようになりました。ですがまだ穴があります。
ログインさえしていれば、他人の商品も書き換えられます。 鈴木さんが田中さんの商品を編集したり、消したりできてしまいます。
ここで認可の出番です。「あなたは誰か」は確かめました。次は「それをしてよいか」です。
出品者と突き合わせる
認証ミドルウェアが req.user を用意してくれているので、それと商品の出品者を比べます。
JavaScript
app.put("/items/:id", requireAuth, (req, res) => {
const item = db.prepare("SELECT * FROM items WHERE id = ?").get(Number(req.params.id));
if (!item) {
return res.status(404).json({ error: "商品が見つかりません" });
}
if (item.owner !== req.user.name) {
return res.status(403).json({ error: "この商品は編集できません" });
}
// ここから先は、自分の商品だと分かっている
});第5章の入力検証と同じ構図です。手前で確かめ、奥では信じる。
403 は取り消せない
第7章の最初に書いたとおり、401 と 403 は意味が違います。
401 はログインすれば通ります。403 はログインし直しても通りません。他人の商品は、誰としてログインしても他人の商品だからです。
受け取った側は、この違いで「ログイン画面へ送るのか、それとも諦めてもらうのか」を決められます。
404 と 403 のどちらを先に見るか
上の例では 404 を先に見ています。素直な順番です。
ただし、より慎重な作りでは他人の商品には 404 を返すこともあります。403 を返すと「その id の商品は存在する」と教えることになるからです。
どちらが正しいというより、何を隠したいかで決まります。fleama の商品は誰でも一覧で見られるので、存在を隠す意味はありません。ですから素直に 403 を返します。
認証と認可は場所が違う
| どこに書くか | 理由 | |
|---|---|---|
| 認証 | ミドルウェア | どのルートでも同じ処理 |
| 認可 | 各ルートの中 | 何と突き合わせるかがルートごとに違う |
出品は「ログインしていれば誰でも」、編集は「出品者だけ」、購入は「出品者以外」かもしれません。条件がルートごとに違うので、まとめられません。
手を動かす
演習では、自分の出品だけ編集・削除できるようにします。404 と 403 の順番にも気をつけてください。
要件
PUT /items/:idとDELETE /items/:idの両方にrequireAuthを掛ける- 商品が無ければ 404、出品者が
req.user.nameと違えば 403 を返す - 通れば編集は
{id, name, owner}を 200 で、削除は 204 を本文なしで返す
ヒント
編集 ゆめさく編集部