| title | Cookieと認証(発展) |
|---|
import cookieCounterVideo from "./cookie-counter.mp4"; import cookieCounterInspectionVideo from "./cookie-counter-inspection.mp4"; import simpleAuthenticationVideo from "./simple-authentication.mp4";
多くのWebアプリケーションは、利用者が本人であることを確認するための機能を備えています。この節では、Webアプリケーションにおける「ログイン」機能を実装するための、最も基本的な技術要素について学びます。
:::danger 認証は、Webアプリケーションのセキュリティにおいて非常に重要な要素で、この節で学ぶ内容のみでは、実際のアプリケーション向けの実装としては不十分です。Firebase AuthenticationやAuth0などの外部サービスを用いることで、強固なセキュリティを手軽に実現できます。また、どうしても外部サービスを利用できない場合は、Passport.jsや、Auth.jsなどのライブラリを利用することを強く推奨します。 :::
IDとパスワードによる認証は、Webアプリケーションにおいて最も一般的な認証方法です。アプリケーションの利用者は、ID(通常はメールアドレスやユーザー名)とパスワードを入力し、サーバーは、その組み合わせをデータベースに保存されているものと比較し、一致すれば認証が成功したと判断します。
認証に成功すると、サーバーはクライアントに対し、一時的な「証明書」を発行します。クライアントは、その証明書を次回以降のリクエストに含めることで、認証が成功していることをサーバーに示します。サーバーは、その証明書の正当性を確認することで、リクエストが正規のユーザーからのものであることを判断します。
Webアプリケーションのクライアントが、サーバーから発行された証明書を保管しておく手段として、もっともよく用いられるのがCookieです。Cookieは、ブラウザ内に保存される小さなデータで、文字列のキーと値のペアとして保存されます。
Cookieを操作するための最も基本的な方法は、HTTPリクエストやレスポンスのヘッダを用いて送受信することです。HTTPレスポンスヘッダにSet-Cookieヘッダを含めることにより、次回以降のリクエストで、クライアントはそのデータをCookieリクエストヘッダに入れて毎回送信します。例えば、
Set-Cookie: name=tanakaSet-Cookie: age=20
のようなHTTPレスポンスヘッダを受け取ったブラウザは、name=tanakaとage=20という2つのキーと値のペアをCookieとして保存します。そして、次回以降のリクエストでは、
Cookie: name=tanaka; age=20
のようなヘッダがリクエストに含まれるようになります。
次の例は、アクセスした回数をCookieに保存し、アクセスのたびにその値を1増やして表示するプログラムです。アクセス回数はCookieに保存されており、サーバーはその値を通してアクセスされた回数を把握しています。
Expressを用いてSet-Cookieヘッダをレスポンスに設定するには、express.Response#cookieメソッドを使用するのが一般的です。また、cookie-parserパッケージを使用すると、リクエストヘッダに含まれるCookieを簡単に取得できます。このパッケージは、request.headers.cookieを解析し、request.cookiesプロパティにオブジェクト形式で格納します。
import express from "express";
import cookieParser from "cookie-parser";
const app = express();
app.use(cookieParser());
app.get("/", (request, response) => {
// Cookieの値は文字列なので数値に変換が必要
const count = Number(request.cookies.count) || 0;
const newCount = count + 1;
// 変更後の値をレスポンスヘッダに乗せる
response.cookie("count", newCount.toString());
response.send(`${newCount}回目のアクセスですね。`);
});
app.listen(3000);{
"dependencies": {
"cookie-parser": "^1.4.7",
"express": "^5.1.0"
}
}