認証の基礎
認証(Authentication)は「誰がアクセスしているか」を確認する仕組み。JWT(JSON Web Token)を使った現代的な認証方式を学びます。
認証と認可の違い
認証(Authentication)
「あなたは誰ですか?」を確認
- ・ログイン処理
- ・ユーザーIDの特定
- ・パスワード/トークン検証
認可(Authorization)
「あなたは何ができますか?」を確認
- ・アクセス権限チェック
- ・自分の記事のみ編集可能
- ・管理者のみ削除可能
認証方式の比較
| 方式 | 特徴 | 用途 |
|---|---|---|
| セッション | サーバーに状態を保持、Cookieで管理 | 従来のWebアプリ |
| JWT | トークンに情報を含む、ステートレス | SPA、モバイル、API |
| OAuth 2.0 | 外部サービスで認証(Google, GitHub等) | ソーシャルログイン |
このコースでは:APIに適したJWT認証を実装します。
JWT(JSON Web Token)とは
JWTの構造
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3MDU0MTIwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header: アルゴリズム情報
Payload: ユーザー情報、有効期限など
Signature: 改ざん検知用の署名
Payloadの例
{
"user_id": 1,
"email": "user@example.com",
"exp": 1705412000, // 有効期限
"iat": 1705325600 // 発行日時
}
JWT認証のフロー
1
ログインリクエスト
クライアント → サーバー: email, password を送信
2
認証処理
サーバー: パスワードをハッシュと照合、JWTを生成
3
トークン返却
サーバー → クライアント: JWTトークンを返す
4
トークン保存
クライアント: トークンをlocalStorageに保存
5
認証が必要なリクエスト
クライアント → サーバー: Authorizationヘッダーにトークンを付与
Authorization: Bearer eyJhbGciOiJ...
6
トークン検証
サーバー: 署名を検証、有効期限を確認、ユーザー情報を取得
パスワードのハッシュ化
絶対にやってはいけないこと:パスワードを平文(そのまま)でデータベースに保存しない!
bcryptでハッシュ化
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# ハッシュ化(登録時)
password = "user_password"
hashed = pwd_context.hash(password)
# → "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"
# 検証(ログイン時)
pwd_context.verify(password, hashed) # True
pwd_context.verify("wrong_password", hashed) # False
bcryptは同じパスワードでも毎回異なるハッシュを生成(ソルト付き)
セキュリティの注意点
SECRET_KEYを公開しない
JWTの署名に使う秘密鍵は環境変数で管理、Gitにコミットしない
トークンの有効期限を短くする
アクセストークンは15分〜1時間程度。リフレッシュトークンで更新
HTTPSを使用する
トークンが盗聴されないよう、本番環境では必ずHTTPS
XSS対策
localStorageに保存したトークンはXSS攻撃で盗まれる可能性。httpOnly Cookieの検討も
まとめ
- ✓ 認証は「誰か」を確認、認可は「何ができるか」を確認
- ✓ JWTはステートレスでAPI向きの認証方式
- ✓ パスワードは必ずbcryptでハッシュ化
- ✓ SECRET_KEYは絶対に公開しない