🏁 はじめに
「ログインって、どうやって“ログインしたまま”を覚えているんだろう?」
「CookieとかJWTってよく聞くけど、違いがよくわからない…」
この記事では、Webアプリのログインの仕組みをテーマに、Cookie、JWT、認証・認可、ログインの流れ、パスワード保護までを初心者にもわかりやすく解説します。
🌐 HTTPはステートレスな通信
まず大前提として、 HTTPはステートレス(stateless) な通信です。
これはつまり、1回1回のリクエストが完全に独立しており、サーバーは過去の状態を覚えていないということです。
● どういうこと?
例えば次のような流れを考えてみましょう。
/login にアクセスしてログイン
次に /mypage にアクセス
サーバーはこのとき、「この人はさっきログインしたユーザーだな」とは分かりません。
HTTP通信は、リクエストごとに新規のやりとりとして扱われるからです。
そのため、サーバーはログイン状態(=状態、state)を覚えておく仕組みを別途用意する必要があります。
その“記憶装置”として生まれたのが Cookie です。
🍪 Cookieとは?
Cookie(クッキー)は、ブラウザに保存される小さなデータです。
サーバーが「この情報を保存しておいて」とブラウザに命令し、次回アクセス時に自動でその情報をサーバーに返す仕組みです。
例えるなら、お店の会員カードのようなものです。カードを提示すると、「あなたは前回も来たお客様ですね」と分かるのと同じです。
● Cookieが使われる代表的な用途
-
ログイン状態の維持(セッションIDやJWTを保存)
-
ユーザー設定(言語・テーマなど)
-
トラッキング(アクセス解析など)
● Cookieのセキュリティ属性
Cookieは便利ですが、扱いを誤ると攻撃の温床にもなります。
安全に使うためには以下の属性を設定します。
| 属性名 | 説明 |
|---|---|
| HttpOnly | JavaScriptからアクセスできないようにする(XSS対策) |
| Secure | HTTPS通信時のみ送信 |
| SameSite | 他サイト経由で送らないようにする(CSRF対策) |
| expires | 有効期限を設定する(不要な情報保持対策) |
🔐 JWT(JSON Web Token)とは?
JWT(JSON Web Token)は、署名付きの認証情報を含んだ文字列トークンです。
セッションのようにサーバー側に状態を保存せず、トークン自体が「誰であるか」の情報を含むのが特徴です。
構造は以下の3部構成👇
header.payload.signature
| 部分 | 内容 |
|---|---|
| Header | トークンの種類と署名アルゴリズム |
| Payload | ユーザー情報(例:user_id, expなど) |
| Signature | 改ざん防止のための署名 |
● どう使われるの?
-
ユーザーがログイン情報を送信
-
サーバーがユーザーを認証し、JWTを発行
-
ブラウザがJWTをCookieやLocalStorageに保存
-
以後のリクエストでJWTを送信し、サーバーが署名を検証
サーバーはトークン自体に情報を持たせるため、 状態を保持しなくても認証できる(ステートレス認証) のが特徴です。
✅ 認証と認可の違い
| 用語 | 意味 | 例 |
|---|---|---|
| 認証(Authentication) | 「誰なのか」を確認する | ログインフォームでID・パスワード確認 |
| 認可(Authorization) | 「何ができるか」を決める | 一般ユーザーは管理画面に入れない |
🧭 ログインの管理方式
① セッション方式(Cookieベース)
サーバー側でユーザーの状態(セッション)を保持します。
🟢 特徴
-
状態(セッション情報)をサーバーが保持
-
CookieにセッションIDのみを保存
-
比較的安全で扱いやすい(httpOnly設定推奨)
🔴 デメリット
サーバー側に状態を保存するため、サーバーが増えると同期が必要となる
② トークン方式(JWTベース)
🟢 特徴
-
サーバーは状態を保持しない(ステートレス認証)
-
APIやモバイルアプリとの相性が良い
-
スケーラブル(複数サーバーでも問題なし)
🔴 デメリット
- トークンを失効させる仕組み(リフレッシュトークン管理)が必要
🔁 ログインの流れまとめ図
| ステップ | セッション方式 | トークン方式(JWT) |
|---|---|---|
| 1 | フォームでID・パスワード送信 | 同じ |
| 2 | サーバーが認証 | サーバーが認証 |
| 3 | セッションIDを生成しCookieに設定 | JWTを生成しブラウザに返す |
| 4 | Cookieが自動で送信される | リクエストヘッダにJWTを付与して送信 |
| 5 | サーバーがセッションIDでユーザー照合 | サーバーがJWT署名を検証 |
| 6 | ログイン状態を維持 | ステートレスに認証を維持 |
🚪 ログアウトの仕組み
● セッション方式
サーバー側のセッションを削除することでログアウトを実現します。
→ Cookieに残っていても、サーバー上にデータがなければ無効。
● トークン方式
サーバー側に状態を持たないため、以下のいずれかで実現します。
-
トークンの有効期限を短くする
-
ブラックリストを導入して「無効化」したトークンを記録する
-
リフレッシュトークンを使って再発行を管理する
🔒 パスワードの安全な扱い方
🧂 ハッシュ化(bcrypt / Argon2など)
パスワードはハッシュ化して保存するのが基本です。
同じ文字列でも「ソルト」を加えることで異なる値に変換します。
| 種類 | 目的 | 元に戻せるか |
|---|---|---|
| ハッシュ化 | 照合用に変換 | ❌ 不可 |
| 暗号化 | 後で復号できるよう変換 | ⭕ 可能 |
● ハッシュ化の例
パスワードは平文で保存せず、 ハッシュ化して保存 します。
password123 → $2b$12$9JzF...
※ 「ソルト(salt)」とは、ハッシュ化する前にパスワードに追加するランダムな文字列のことです。
✅ 暗号化
通信経路などで第三者に見られないようにデータを 「復号可能な形」 で保護します。
鍵を持つ人だけが元のデータを復元できます。
● HTTPS(TLS通信)
パスワードがハッシュ化されていても、通信が暗号化されていなければ途中で盗み見られる危険があります。
そこで使われるのが HTTPS(TLS暗号化通信) です。
HTTPSを使うことで、ブラウザとサーバー間のデータが暗号化され、
安全にパスワードやトークンをやり取りできます。
⚙️ セキュリティ上の注意点
| 項目 | 内容 |
|---|---|
| CookieのHttpOnly属性 | XSS対策として必須 |
| SameSite属性 | CSRF対策に有効 |
| JWTの有効期限 | 長すぎないように設定 |
| リフレッシュトークン | アクセストークン再発行に使用 |
| HTTPS | 通信経路の暗号化は必須 |
| expires属性 | 不要な情報保持対策 |
🔐 さらに安全にするには(多要素認証)
パスワード+ワンタイムコード(SMS / アプリ)や指紋・顔認証などを組み合わせる 多要素認証(MFA / 2FA) を導入すると、アカウント乗っ取りリスクを大幅に減らせます。
🧱 まとめ
| 項目 | 概要 |
|---|---|
| HTTPはステートレス | 状態を保持できないためCookieが必要 |
| Cookie | サーバーがユーザー情報を追跡する仕組み |
| JWT | サーバーが状態を持たないトークン認証 |
| 認証と認可 | 「誰か」と「何ができるか」を分けて考える |
| セッション方式 | サーバーで状態管理(安全・簡単) |
| トークン方式 | ステートレスでAPIに最適 |
| パスワード保護 | ハッシュ化+HTTPS+MFAが鍵 🔑 |
💬 おわりに
「ログイン」という機能の裏側には、HTTPのステートレス性、Cookie、JWT、認証・認可、パスワード管理、HTTPS通信など多くの技術が組み合わさっています。
仕組みを理解することで、「ただ動くログイン」から「安全で信頼できるログイン」へとステップアップできます。
最後までご覧いただきありがとうございました。他にも記事を投稿しておりますので、ご興味がございましたら、是非そちらもご覧ください。また間違っているなどございましたら、教えて頂けると幸いです。よろしくお願いします。