web-dev-qa-db-ja.com

認証:JWTの使用法とセッション

認証などの状況でセッションを使用することに対するJWTの利点は何ですか?

それはスタンドアロンのアプローチとして使用されますか、それともセッションで使用されますか?

75
Pourya8366

JWTには、「セッション」を使用する以上の利点はありません。 JWTは、サーバーでセッション状態を実行する代わりに、クライアントでセッション状態を維持する手段を提供します。

これを尋ねるときによく言われるのは、「サーバー側セッションを使用するよりもJWTを使用する利点は何ですか」

サーバー側のセッションでは、セッション識別子をデータベースに保存するか、メモリに保存して、クライアントが常に同じサーバーにアクセスするようにする必要があります。どちらにも欠点があります。データベース(または他の中央ストレージ)の場合、これはボトルネックになり、維持する必要があります。基本的に、すべての要求で実行される追加のクエリです。

インメモリソリューションを使用すると、水平スケーリングを制限でき、セッションはネットワークの問題(Wifiとモバイルデータ間のローミングクライアント、サーバーの再起動など)の影響を受けます。

セッションをクライアントに移動するということは、サーバー側セッションへの依存関係を削除することを意味しますが、独自の一連の課題を課します。
-トークンを安全に保存する
-安全に輸送する
-JWTセッションを無効化するのが難しい場合があります。
-クライアントの主張を信頼する。

これらの問題は、JWTや他のクライアント側のセッションメカニズムでも同様に共有されます。

特に、JWTはこれらの最後に対処します。 JWTが何であるかを理解すると役立つ場合があります。

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

トークンは署名されているため、サーバーはそのオリジンを検証できます。サーバーは、安全に署名する独自の機能を信頼していると想定します(標準ライブラリを使用する必要があります。自分で実行しないで、サーバーを適切に保護してください)

トークンを安全に転送する際の問題については、通常、暗号化されたチャネル(通常はhttpS)を介してトークンを送信します。

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

JWTを無効にする必要がある場合、これを確実に実現する方法があります。 「他のセッションを終了する」ように要求したユーザーのみにユーザーごとのエポックを保存することは、おそらく十分に効率的な方法です。アプリケーションがセッションごとの無効化を必要とする場合、セッションIDは同じ方法で維持でき、「killed tokens」テーブルは完全なユーザーテーブルよりもはるかに小さく維持できます(レコードを保持する必要があるのは、そのため、トークンを無効にする機能は、このセッションの強制終了状態を維持する必要があるという点で、クライアント側セッションの利点を部分的に無効にします。これはおそらく元のセッション状態テーブルよりもはるかに小さなテーブルになるため、ルックアップはさらに効率的です。

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

より微妙な利点:JWTが「情報」を運ぶことができ、クライアントがこれにアクセスできるため、スマートなことを開始できるようになりました。たとえば、ユーザーがログアウトする数日前にセッションが期限切れになることをユーザーに思い出させ、トークンの有効期限に基づいて再認証するオプションをユーザーに与えます。あなたが想像できるものは何でも。

つまり、JWTは他のセッションテクニックの質問と欠点のいくつかに答えます。
1。 DBラウンドトリップ(または少なくともクエリするテーブルがはるかに小さい!)を排除できるため、「安価な」認証が可能になります。これにより、水平方向のスケーラビリティが実現します。
2。改ざん防止のクライアント側クレーム。

JWTは、安全なストレージやトランスポートなどの他の問題には答えませんが、新しいセキュリティの問題は発生しません。

JWTには多くの否定性がありますが、他のタイプの認証と同じセキュリティを実装する場合は問題ありません。

最後に、CookiesとTokensではありません。 Cookieは、情報のビットを格納および転送するためのメカニズムであり、JWTトークンの格納および転送にも使用できます。

129
The Tahaan

短い答えは:なし。

長いバージョンは次のとおりです。

GraphQL docs でこの推奨事項を読んだ後、セッション管理用のJWTを実装しました。

これらの認証メカニズムになじみがない場合は、express-jwtを使用することをお勧めします。これは、将来の柔軟性を犠牲にすることなくシンプルだからです。

実装は、ほんの少しの複雑さを追加するだけで、本当に簡単でした。しかし、しばらくして、私は(あなたのように)利益が何であるかと思い始めました。このブログ投稿で詳細に説明されているように、セッション管理に関する限り、JWTについては非常に少ない(またはおそらくない)ことが判明しています。

セッションでのJWTの使用を停止

25
Carl von Blixen