保護ルート
トークンを毎回確かめる
トークンを発行できました。次は、それを持っている人だけを通す仕組みです。
トークンはヘッダーに入れて送るのが決まりです。
プレーンテキスト
Authorization: Bearer 3f7a1c...Bearer は「持参人」という意味の決まり文句で、その後ろがトークンです。読むときは前置きを取り除きます。
JavaScript
const header = req.headers.authorization || "";
const token = header.replace("Bearer ", "");認証ミドルウェアを書く
第5章で学んだミドルウェアの出番です。通してよければ next()、だめなら止める。
JavaScript
function requireAuth(req, res, next) {
const token = (req.headers.authorization || "").replace("Bearer ", "");
if (!token) {
return res.status(401).json({ error: "ログインしてください" });
}
const user = db.prepare("SELECT id, name FROM users WHERE token = ?").get(token);
if (!user) {
return res.status(401).json({ error: "ログインしてください" });
}
req.user = user;
next();
}第5章で「next() を呼び忘れると止まる」と書きました。ここではわざと止めています。401 を返して、リクエストをルートまで届けません。
req に持たせて渡す
JavaScript
req.user = user;この 1 行が大切です。ミドルウェアで分かった「誰か」を req に付けておくと、その先のルートで使えます。
JavaScript
app.post("/items", requireAuth, (req, res) => {
// ここでは req.user が必ずある
});次のレッスンの認可では、この req.user と出品者を突き合わせます。
必要なルートにだけ付ける
app.use で全体に掛けると、商品一覧までログイン必須になります。フリマとしては、見るのは誰でもできるほうが自然です。
JavaScript
app.get("/items", (req, res) => { ... }); // 誰でも見られる
app.post("/items", requireAuth, (req, res) => { ... }); // 出品はログイン必須ルートの 2 つ目の引数として渡すと、そのルートにだけ掛かります。守るものと開けておくものを、意識して分けてください。
手を動かす
演習では、認証ミドルウェアを書いて、出品だけをログイン必須にします。
要件
requireAuthはトークンが無い・一致しないなら 401 で{"error":"ログインしてください"}を返す- 通ったら
req.userに利用者を入れてnext()を呼ぶ POST /itemsにだけ掛け、GET /itemsは誰でも見られるままにする
入出力例
request("GET", "/items") → "200 [{"id":1,"name":"レザースニーカー","owner":"田中"}]"
request("POST", "/items", {"name":"木製のスツール"}) → "401 {"error":"ログインしてください"}"
request("POST", "/items", {"name":"木製のスツール"}, "detarame") → "401 {"error":"ログインしてください"}"
request("POST", "/items", {"name":"木製のスツール"}, "token-tanaka") → "201 {"id":2,"name":"木製のスツール","owner":"田中"}"ヒント
編集 ゆめさく編集部