JWTは良いのか?
JWTは悪い
結論から言うと、限定的なビジネス要件でのみ有用になり得ると考える。
概要
私は多くのプロジェクトをやったわけではないが、経験的に最近のWebサービスの認証処理にJWTを使用する場合が多いようだ。 ホットな技術なので勉強してプロジェクトにも適用してみたが、知れば知るほど限定的にしか有用でなく、特にジュニア(私のような人たち..)が技術の長所/短所をよく知らずに使用しているようで、確実に指摘して進みたいと思った。
スケーラブルなインフラで...
JWTの最大の利点は無状態性にある。
JWTはトークンを署名するための暗号鍵だけで、該当認証情報の有効性を検証できる。
セッションの場合、その特徴によりメモリや外部DBにセッションキーを保存しなければならないため、セッションキーを持つ特定のサーバーに認証が依存する問題(stateful)がある。
なぜstatefulなのが問題かというと、多重化されたアプリケーション環境では、すべてのアプリケーションが同じデータを見なければならないため、セッションキーが中央集約された何らかのサーバーで管理されなければならない問題が発生する。
JWTは暗号鍵だけで有効性検証が可能なので、このような問題から自由になれる。
じゃあ良いことじゃない?
「じゃあハッピーじゃない?」と思うかもしれないが、問題はビジネス要件から発生する。 サービス中に悪意のあるユーザー(例:ハッカー、スパムユーザー...)をBanしなければならないというビジネス要件は一般的だ。(そうではないか?)
この要件を実装するために、一般的にAccessTokenとRefreshTokenを置き、RefreshTokenをインメモリでもRDBでもどこかに保存した後、必要に応じて照会して無効化処理する。 認証過程で'保存および照会'プロセスが発生する場合、今やあなたの認証過程はStatefulになった。
この場合、上で説明したセッションと同様に、中央集約型キャッシュサーバーが必要になる。
もちろんセッションとの違いはある。
Access+Refreshの組み合わせで実装された認証では、AccessTokenをどこかに保存しないため、AccessTokenが有効な間は外部キャッシングサーバーにネットワークI/Oしない利点がある。 この場合、毎回ネットワークI/Oが必要なセッションに比べて、Access + Refreshの組み合わせの認証がコストが低い可能性が高く見える。
モノリシックインフラで...
無状態性がなぜ必要?
多重化を考慮しないモノリシックアプリケーションでは、無状態性を持つ必要がない。(結局リクエストを一つのサーバーでしか受け取らないから..) この時はメモリさえ十分なら、セッションキーをメモリに保存してO(1)で取得するセッション方式が、デコーディングと検証プロセスがあるJWTに比べてコスト的に安いだろう。
まとめ
トレンド性だけを追い求めず、ビジネスと技術の長所/短所をよく考慮して選択できる開発者になろう。