@@ -9,7 +9,7 @@ import simpleAuthenticationVideo from "./simple-authentication.mp4";
99多くのWebアプリケーションは、利用者が本人であることを確認するための機能を備えています。この節では、Webアプリケーションにおける「ログイン」機能を実装するための、最も基本的な技術要素について学びます。
1010
1111:::danger
12- 認証やセッション管理は 、Webアプリケーションのセキュリティにおいて非常に重要な要素で、この節で学ぶ内容のみでは、実際のアプリケーション向けの実装としては不十分です。[ Firebase Authentication] ( https://firebase.google.com/products/auth ) や[ Auth0] ( https://auth0.com/ ) などの外部サービスを用いることで、強固なセキュリティを手軽に実現できます。また、どうしても外部サービスを利用できない場合は、[ Passsport .js] ( https://www.passportjs.org/ ) や、[ Auth.js] ( https://authjs.dev/ ) などのライブラリを利用することを強く推奨します。
12+ 認証は 、Webアプリケーションのセキュリティにおいて非常に重要な要素で、この節で学ぶ内容のみでは、実際のアプリケーション向けの実装としては不十分です。[ Firebase Authentication] ( https://firebase.google.com/products/auth ) や[ Auth0] ( https://auth0.com/ ) などの外部サービスを用いることで、強固なセキュリティを手軽に実現できます。また、どうしても外部サービスを利用できない場合は、[ Passport .js] ( https://www.passportjs.org/ ) や、[ Auth.js] ( https://authjs.dev/ ) などのライブラリを利用することを強く推奨します。
1313:::
1414
1515## IDとパスワードによる認証
@@ -39,7 +39,7 @@ Cookieを操作するための最も基本的な方法は、HTTPリクエスト
3939
4040![ Cookieを利用したアクセスカウンタの処理の流れ] ( ./cookie-counter-flow.drawio.svg )
4141
42- Expressを用いて` Set-Cookie ` ヘッダをレスポンスに設定するには、[ ` express.Response#cookie ` メソッド] ( https://expressjs.com/ja/api.html#res.cookie ) メソッドを使用するのが一般的です 。また、[ cookie-parser] ( https://www.npmjs.com/package/cookie-parser ) パッケージを使用すると、リクエストヘッダに含まれるCookieを簡単に取得できます。このパッケージは、` request.headers.cookie ` を解析し、` request.cookies ` プロパティにオブジェクト形式で格納します。
42+ Expressを用いて` Set-Cookie ` ヘッダをレスポンスに設定するには、[ ` express.Response#cookie ` メソッド] ( https://expressjs.com/ja/api.html#res.cookie ) を使用するのが一般的です 。また、[ cookie-parser] ( https://www.npmjs.com/package/cookie-parser ) パッケージを使用すると、リクエストヘッダに含まれるCookieを簡単に取得できます。このパッケージは、` request.headers.cookie ` を解析し、` request.cookies ` プロパティにオブジェクト形式で格納します。
4343
4444``` javascript title="main.mjs" showLineNumbers
4545import express from " express" ;
@@ -50,7 +50,7 @@ app.use(cookieParser());
5050
5151app .get (" /" , (request , response ) => {
5252 // Cookieの値は文字列なので数値に変換が必要
53- const count = Number . parseInt (request .cookies .count ) || 0 ;
53+ const count = Number (request .cookies .count ) || 0 ;
5454 const newCount = count + 1 ;
5555 // 変更後の値をレスポンスヘッダに乗せる
5656 response .cookie (" count" , newCount .toString ());
@@ -91,8 +91,7 @@ Cookieを使用して、実際に認証が必要なWebアプリケーション
9191
9292<video src = { simpleAuthenticationVideo } controls muted />
9393
94- <Tabs >
95- <TabItem value = " server" label = " サーバー" >
94+ ### サーバー
9695
9796このアプリケーションでは、ユーザー情報を保存するテーブル` User ` と、セッション情報を保存するテーブル` Session ` の2つを持つデータベースを使用します。` Session ` テーブルには、一意でランダムなIDである` sessionId ` と、ユーザーのIDである` userId ` が保存されます。サーバーは、クライアントが` sessionId ` を知っていれば、その` userId ` に対応するユーザーとしてクライアントを認証します。つまり、この` sessionId ` が、前述の「証明書」に相当します。
9897
@@ -112,7 +111,9 @@ model Session {
112111}
113112```
114113
115- ` /login ` は、IDとパスワードを含むJSON形式のPOSTリクエストを受け取り、データベースの` User ` テーブルのデータと比較することで、認証情報が正しいかどうかを検証します。正しければ、新しいレコードを` Session ` テーブルに作成し、その` sessionId ` をCookieとしてクライアントに送信します。誤っていれば、直ちに認証失敗の<Term >ステータスコード</Term >を返して終了します。
114+ ` /login ` は、IDとパスワードを含むJSON形式のPOSTリクエストを受け取り、データベースの` User ` テーブルのデータと比較することで、認証情報が正しいかどうかを検証します。正しければ、[ ` crypto.randomUUID ` 関数] ( https://developer.mozilla.org/ja/docs/Web/API/Crypto/randomUUID ) を用いてランダムな文字列を生成し、新しいレコードを` Session ` テーブルに作成した上で、Cookieとしてクライアントに送信します。誤っていれば、直ちに認証失敗の<Term >ステータスコード</Term >を返して終了します。
115+
116+ 新しいレコードを` Session ` テーブルに作成し、その` sessionId ` をCookieとしてクライアントに送信します。誤っていれば、直ちに認証失敗の<Term >ステータスコード</Term >を返して終了します。
116117
117118``` javascript title="main.mjs (POST /login の抜粋)" showLineNumbers
118119app .post (" /login" , async (request , response ) => {
@@ -132,7 +133,7 @@ app.post("/login", async (request, response) => {
132133 data: { userId: user .id , sessionId: crypto .randomUUID () },
133134 });
134135 response .cookie (" sessionId" , session .sessionId );
135- response .send (200 ); // OK (成功)
136+ response .sendStatus (200 ); // OK (成功)
136137});
137138```
138139
@@ -163,14 +164,13 @@ app.get("/profile", async (request, response) => {
163164});
164165```
165166
166- </TabItem >
167- <TabItem value = " client" label = " クライアント" >
167+ ### クライアント
168168
169- クライアント側のアプリケーションは、認証が必要なページ` / ` とログインページ` /login ` の2から構成されています 。
169+ クライアント側のアプリケーションは、認証が必要なページ` / ` とログインページ` /login ` の2つから構成されています 。
170170
171171` / ` では、ページが読み込まれたときに` /profile ` にGETリクエストを送信し、認証が成功すればユーザー名を表示します。認証に失敗した場合は、ログインページに移動します。
172172
173- ``` html title="public/index.html" showLineNumbers
173+ ``` html title="public/index.html (抜粋) " showLineNumbers
174174<h1 >ホーム</h1 >
175175<p >ようこそ!<span id =" username-display" ></span >さん!</p >
176176```
@@ -228,10 +228,11 @@ document.getElementById("login-button").onclick = async () => {
228228};
229229```
230230
231- </TabItem >
232- </Tabs >
233-
234- <ViewSource url = { import .meta .url } path = " _samples/simple-authentication" />
231+ <ViewSource
232+ url = { import .meta .url }
233+ path = " _samples/simple-authentication"
234+ noCodeSandbox
235+ />
235236
236237全体の処理の流れは、次の図のようになります。
237238
0 commit comments