ウェブサイトやアプリで「ログイン」するとき、あなたの身元を確認する仕組みが裏側で働いています。この仕組みを「認証」と呼び、目的や安全性によっていくつかの方法があります。ここでは代表的な認証方式を、図解とポイント解説でわかりやすく整理していきます。
Basic認証
sequenceDiagram
participant U as ユーザー
participant B as ブラウザ
participant S as サーバー
B->>S: GET /page
S-->>B: 401 Unauthorized + WWW-Authenticate: Basic realm="example"
U->>B: IDとパスワードを入力
B->>S: Authorization: Basic Base64("ID:PASS")
S-->>B: 200 OK + ページ内容
ポイント
- サーバーは401レスポンスと一緒に `WWW-Authenticate` ヘッダを返すことで、ブラウザに認証を要求する。
- ブラウザはユーザーが入力したIDとパスワードを `ID:PASS` という文字列にし、それをBase64でエンコードして送信する。
- Base64は暗号化ではなく単なる文字変換。復号は誰でも簡単にできるため、平文送信とほぼ同じ危険性を持つ。
- そのため、Basic認証を安全に使うには HTTPSが必須。暗号化されていないHTTPで使うと、通信を盗聴されれば認証情報が即座に漏れる。
Digest認証
Basic認証を改良した方式で、パスワードをそのまま送らずにハッシュ値を送信する。
これにより、盗聴されても平文パスワードが直接漏れない仕組みになっている。
sequenceDiagram
participant U as ユーザー
participant B as ブラウザ
participant S as サーバー
B->>S: GET /page
S-->>B: 401 Unauthorized + WWW-Authenticate: Digest (nonce)
U->>B: ユーザー名&パスワード入力
B->>S: Authorization: Digest (username, nonce, ハッシュ値)
S-->>B: 200 OK ページ表示
ポイント
- サーバーは401と一緒に nonce(一度きりの乱数)を返し、ブラウザに認証を要求する。
- ブラウザは「ユーザー名 + パスワード + nonce + リクエスト情報」をMD5でハッシュ化し、送信する。
- サーバー側も登録済みのパスワードを使って同じ計算を行い、一致すれば認証成功。
- これにより、パスワード自体は送信されない。過去のリクエストを盗んで再送しても、nonceが変わるため無効化できる。
- ただし、Digest認証はMD5に依存しており、現代ではセキュリティ的に脆弱。現在は BearerトークンやOAuth2、JWTなどが主流。
Cookie認証
ログインに成功すると、サーバーは「セッションID」を発行し、`Set-Cookie` ヘッダでブラウザに渡す。
ブラウザは以降のリクエストで、そのCookieを自動的に送信することで認証を維持する。
sequenceDiagram
participant U as ユーザー
participant B as ブラウザ
participant S as サーバー
U->>S: ユーザー名とパスワード
S-->>B: Set-Cookie: セッションID
B->>S: GET /page (Cookie: セッションID)
S-->>B: 200 OK + ページ内容
ポイント
- セッションID は「サーバーが保持するログイン状態」と対応する鍵のようなもの。
- ブラウザはCookieを自動で添付するため、ユーザーは毎回ログインする必要がない。
- セキュリティのために以下が重要:
Secure
属性でHTTPS通信に限定する
HttpOnly
属性でJavaScriptからの盗み見を防ぐ
SameSite
属性でCSRF攻撃を軽減する
Cookie
認証は「セッション管理」とセットで使われる、昔から一般的な方法。
トークン認証(例: JWT)
ログインするとサーバーが「トークン(署名付きの身分証明書)」を発行し、
以後のリクエストではそのトークンを使って認証を行う。
sequenceDiagram
participant U as ユーザー
participant B as ブラウザ
participant S as サーバー
U->>S: ログインリクエスト (ID & パスワード)
S-->>B: JWTトークン発行
B->>B: トークンを保存
B->>S: リクエスト + Authorization: Bearer:トークン
S-->>B: トークンを検証 (署名確認、有効期限チェック)
S-->>B: 200 OK ページ表示
ポイント
- トークンは「誰がログイン済みか」を証明するデータ。JWTでは秘密鍵で署名され、改ざんできない。
- 毎回ログインし直す必要がなく、ステートレス認証(サーバーがセッションを保持しない)を実現できる。
- 保存方法はCookieやLocalStorageが一般的だが、XSSやCSRFなど攻撃手法に注意が必要。
- トークンには有効期限があり、長期利用には「リフレッシュトークン」で更新する仕組みがよく使われる。
OAuth(例: 「Googleでログイン」)
自分のパスワードをアプリに渡さずに、他のサービス(GoogleやTwitterなど)に「認証・認可」を任せる仕組み。
sequenceDiagram
participant U as ユーザー
participant A as あなたのアプリ
participant G as Google(認証サーバー)
U->>A: 「Googleでログイン」ボタンをクリック
A->>G: 認証リクエスト (この人の情報を取得したい)
G-->>U: Googleのログイン画面を表示
U->>G: ID & パスワード入力
G-->>U: 同意画面 (このアプリにプロフィール閲覧を許可しますか?)
U->>G: 許可する
G-->>A: アクセストークン発行
A->>G: アクセストークンを使ってユーザー情報取得
G-->>A: ユーザー情報返却
A->>U: ログイン完了!
ポイント
- アプリはユーザーのパスワードを一切知らない。
- Googleが「この人は本物」と確認し、さらに「このアプリはプロフィール情報を読む権利がある」と認可する。
- サーバーから渡されるアクセストークンを使って必要な情報にアクセスする。
- 本来のOAuthは「認可」の仕組みで、ログイン用途(認証)に使われるのはOAuth 2.0のよくある使い方の一つ。
まとめ
- Basic認証: IDとパスワードを直接送る(古い、要HTTPS)
- Digest認証: ハッシュを使う(今はほぼ使わない)
- Cookie認証: クッキーに印をつけて確認する
- トークン認証(JWTなど): 合言葉を発行して、それを持ち歩く
- OAuth: 他のサービスに本人確認を頼む