1. ホーム

[解決済み】認証。JWTの使用とセッションの比較

2022-04-04 23:26:25

質問

認証のような状況で、セッションではなくJWTを使用する利点は何ですか?

単体で使用するのか、それともセッションで使用するのか?

どのように解決するのですか?

JWTは、それ自体、"sessions"を使用することに勝る利点があるわけではありません。 JWTは、サーバー上で行う代わりに、クライアント上でセッションの状態を維持する手段を提供します。

この質問をするときによく言われるのは、「JWTを使うメリットは何ですか? サーバーサイドセッション となります。

サーバーサイドセッションでは、セッション識別子をデータベースに保存するか、メモリに保存して、クライアントが常に同じサーバーにアクセスするようにしなければならないでしょう。 このどちらにも欠点があります。 データベース(または他の集中型ストレージ)の場合、これはボトルネックになり、維持するものになります - 基本的に、リクエストごとに実行される余分なクエリです。

インメモリーソリューションでは、水平方向のスケーリングが制限され、セッションはネットワークの問題(クライアントがWifiとモバイルデータを行き来する、サーバーが再起動する、など)の影響を受けることになります。

セッションをクライアントに移すということは、サーバー側のセッションへの依存をなくすということですが、それなりの課題があります。

  • トークンを安全に保管する。
  • 安全に持ち運ぶ。
  • JWTセッションは、時に無効化することが困難な場合があります。
  • クライアントの主張を信用すること。

これらの問題は、JWTや他のクライアント側セッションの仕組みにも共通するものです。

特にJWTは、このうちの最後に対応しています。 JWTが何であるかを理解するのに役立つかもしれません。

それは、ちょっとした情報です。 ユーザーセッションの場合、ユーザー名とトークンの有効期限を含めることができます。 しかし、セッションIDやユーザーのプロファイル全体を含めることも可能です(ただし、そのようなことはしないでください)。 悪意のある者が偽のトークンを生成するのを防ぐために、安全な署名があります(署名するにはサーバーの秘密鍵にアクセスする必要があり、署名後に変更されていないことを確認できます)。 このトークンは、クッキーや Authorization ヘッダが送信されます。 実際、一般的に送信されるのは、HTTPの Authorization ヘッダを使用することもできますが、クッキーを使用しても問題ありません。

トークンは署名されているので、サーバーはその起源を確認することができます。 サーバは自分自身の安全な署名能力を信頼していると仮定します(標準ライブラリを使用すべきです:自分でやろうとせず、サーバを適切に保護する必要があります)。

トークンの安全な輸送の問題については、暗号化されたチャネル、通常はhttpSを介して送信することが一般的な答えです。

トークンをクライアントに安全に格納することについては、悪者がトークンにアクセスできないようにする必要があります。 これは(ほとんどの場合)、悪質なWebサイトのJSがトークンを読み取って返送するのを防ぐことを意味します。 これは、他の種類のXSS攻撃を緩和するために使用されるのと同じ戦略を使用して緩和されます。

JWTを無効にする必要がある場合、これを実現する方法は確実に存在します。他のセッションを終了させることを要求したユーザーだけのためにユーザーごとのエポックを保存することは、非常に効率的な方法であり、おそらく十分な方法でしょう。 アプリケーションがセッションごとの無効化を必要とする場合、セッションIDを同じ方法で維持することができ、"killed tokens" テーブルは依然として完全なユーザーテーブルよりもはるかに小さく維持することができます(あなたは、許可された最長トークン寿命よりも新しいレコードのみを維持する必要があります)。 つまり、トークンを無効にする機能は、このセッションキル状態を維持する必要があるという点で、クライアントサイドセッションの利点を部分的に否定することになります。 これは、元のセッション状態テーブルよりもはるかに小さなテーブルになる可能性が高いので、ルックアップはより効率的です。

JWTトークンを使用するもう1つの利点は、おそらく期待できるすべての言語で利用可能なライブラリを使って、合理的に簡単に実装できることです。 また、初期のユーザー認証スキームから完全に切り離されています。指紋ベースのシステムに移行する場合、セッション管理スキームに変更を加える必要はありません。

JWTは情報(quot;information")を持ち、クライアントがこれにアクセスできるため、いくつかのスマートなことを始められるようになるのです。 たとえば、ログアウトする数日前にセッションの有効期限が切れることをユーザーに知らせ、トークンの有効期限に基づいて再認証を行うオプションを与えることができます。 想像できることは何でもしてください。

つまり、JWTは他のセッション手法の疑問や欠点に答えてくれるのです。

  1. DBのラウンドトリップをなくすことができるため(または、少なくともクエリするテーブルをかなり小さくすることができるため!)、水平方向のスケーラビリティを可能にします。

  2. クライアント側の主張を改ざんできないようにする。

JWTは、安全なストレージやトランスポートといった他の問題には答えていませんが、新たなセキュリティ問題を引き起こすことはありません。

JWTには否定的な意見が多く存在しますが、他のタイプの認証と同じセキュリティを実装すれば、問題ありません。

最後にもう一つ、Cookie対Tokensでもありません。 クッキーは情報の断片を保存して転送するメカニズムであり、JWTトークンを保存して転送するためにも使用できます。