こんにちは、tampopo256 です。
今回は、自分が実際にやらかしてしまった「セッション管理の失敗」を赤裸々に綴ります。
これからWebアプリを作る人、すでにJWTを使っている人は、「あ、これ自分もやってるかも」と感じるかもしれません。
💥やらかしポイント
① JWTの有効期限を365日に設定していた
開発初期、セッション管理が面倒という理由で、JWTの有効期限を365日に設定していました。
const token = jwt.sign(payload, SECRET_KEY, {
expiresIn: "365d"
})
その結果どうなったか?
- 一度発行したトークンは1年間どこからでも使える状態に
- もしトークンが漏洩すれば、取り返しがつかない
- 有効期限切れの対応処理がなく、トークンが切れたら即ログアウト
これはもう、「セッション管理してるつもり」になっていただけの状態でした。
② リフレッシュトークンを用意していなかった
JWTの期限が切れてしまうと、ユーザーは突然ログアウト状態に。
「なんか急に落とされた」「バグでは?」と感じるユーザー続出。
開発側も「なぜログイン状態が維持されないのか?」と毎回悩む始末。
なぜか?
→ リフレッシュトークンを発行するAPIを作っていなかったからです。
🧯本来どうするべきだったのか
正しいセッション管理の考え方
トークン種別 | 用途 | 有効期限 | 保存場所 | 失効時の対処 |
---|---|---|---|---|
アクセストークン | API認証に使用 | 15〜60分 | メモリ or Cookie | リフレッシュトークンで再取得 |
リフレッシュトークン | 再発行の認証用 | 数日〜数週間 | httpOnly Cookie推奨 | 再ログインを要求 |
実装の全体像(ざっくり)
1. ログイン時に
- アクセストークン(短命)
- リフレッシュトークン(長命)
を発行
2. API通信はアクセストークンで認証
3. アクセストークンが切れたら
→ リフレッシュトークンで再取得
4. 両方切れたら
→ ログイン画面へリダイレクト
🔐アクセストークンとリフレッシュトークンのバランス
JWTは「状態を持たない」トークンですが、それは管理の責任が減るという意味ではない。
実際のシステムでは:
- アクセストークンは短命にして漏洩リスクを抑える
- リフレッシュトークンは厳重に保管して定期的に再発行
- トークンの無効化にはブラックリスト or バージョン管理なども検討
🧵補足:Cookie vs LocalStorage
トークン保存場所としてlocalStorage
を使っていたこともありましたが、XSSに対して無防備でした。
本来であれば以下の通りにするべきです。
- アクセストークン:
httpOnly
なCookie(JSから触れない) - リフレッシュトークン:同様に
httpOnly
Cookieでセキュアに保存
💡まとめ
- 🔥 JWTの長期有効化は危険。
- 🔄 リフレッシュトークンがないと「まともなUX」は作れない。
- 🧠 セキュリティと利便性のバランスを考えるべき。
📝さいごに
セッション管理は、サービスの「入り口」であり「防波堤」です。
そこが雑だと、どんなにUIが良くても、どんなに便利な機能があっても信用を失います。
この記事を読んでくださった方には、ぜひ最初から「ちゃんとしたセッション管理設計」をしてほしいです。