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


122

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

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

回答:


212

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には多くの否定的な点がありますが、他の種類の認証と同じセキュリティを実装すれば問題ありません。

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


4
サーバー側のセッションでもサーバーに情報を保存する必要がないことは注目に値します。サーバーは、JWTと同じ方法でクライアントをストアとして使用できます。実際の違いは、1)Cookieヘッダー以外のリクエストヘッダーとして値を渡すことでブラウザーのセキュリティルールを回避することと、2)JWTで標準化されたフォーマットを持つことです。
Xeoncross、

1
ローカルストレージにjwtを保存しても安全だと思いますか?そうでない場合、ユーザーがログインしたままになるように安全な場所に保存しますか?
ジェシカ

1
はい、ローカルストレージは通常、クライアント側に保存するのに最も適切な場所です。私はこの回答でWebプログラミングの専門家ではなく見ていないよ-あなたはXSSに対処する必要がありますかstackoverflow.com/a/40376819/1810447と「に対するXSSを保護する方法」を検索
Tahaan

1
あなたのコメントでは、キャッシュベースのソリューション+セッショントークンについて話していません。JWT + "killed tokens"テーブルよりも "良い"ように思えます。この "killed tokens"テーブルを使用すると、とにかくセッション+キャッシュ(小さい)も持つDBアクセスが必要になるためです。そして、JWTの永続化は、refresh_token(2つのトークンを維持するため)で遊ぶ必要があるため、永続化セッションよりも実装が面倒です...コメントは本当にありがたいです...特に、JWTをどのように表示するかがある場合は、 kill_tableは、セッション+キャッシュよりも効率的です;-)
tobiasBora

2
@TheTahaan localStorageは、JWTの保管にはお勧めできません。あなたが共有したリンクはそれについても言及しています。このブログには、JWTをlocalStorageに保存してはならない理由が説明されています。
Harke

40

短い答えは次のとおりです。なし。

より長いバージョンは:

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

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

実装はほんの少しの複雑さを追加しただけなので、確かにシンプルでした。しかししばらくして、私(あなたのような)は何の利点があるのか​​疑問に思い始めました。このブログの投稿で詳細に説明されているように、セッション管理に関する限り、JWTの数はほとんどない(またはおそらくない)ことがわかります。

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


0

私の2セントは、途中でjoepie91の有名なブログ投稿と対照的です。

それを考えると、今日の(そして明日の)アプリケーションは、(主に)されているネイティブのクラウド
への経済的利益がありますステートレスJWT認証は、どのアプリケーションのスケールとしてスケール:
1で引き分け、すべての息と一緒にコスト負担クラウドアプリケーション
ユーザーがセッションストアに対して「反対に」認証する必要がなくなると、このコストは削減されます。

処理
セッションストアを24時間年中無休で実行するには、費用がかかります。
ポッドは一時的なものであるため、K8Sの世界ではメモリベースのソリューションを利用できません。
スティッキーセッションは、まったく同じ理由でうまく機能しません。

ストレージ
データの保存にはコストがかかります。SSDへのデータの保存にはさらにコストがかかります。
セッション関連の操作は迅速に解決する必要があるため、光学ドライブはオプションではありません。

I / O
一部のクラウドプロバイダーは、ディスク関連のI / Oに料金を請求しています。

帯域幅
一部のクラウドプロバイダーは、サーバーインスタンス間のネットワークアクティビティに対して課金します。
APIとセッションストアが別々のインスタンスであることがほぼ確実であるため、これが当てはまります。

セッションストア
クラスタリングコストは、前述のすべてのコストをさらに増大させます。


「ポッドは一時的なものであるため、K8Sの世界ではメモリベースのソリューションを利用できません」これが何を意味するのかわからない。Redisは間違いなくK8S環境で機能し、Redisポッドがユーザーに影響を与えるほど頻繁に失敗することはほとんどありません。
quietContest

@quietContest個人的には、ソフトウェアを構築するときに可能性を処理しないことを好みます。ところで、ソリューションの安定性はさておき、攻撃によりソフトウェアが失敗し、ポッドが再起動する可能性があり、セッションが失われる可能性があります。そのため、私はJWTベースのソリューションを選択します。
Eyal Perry

1
「私は個人的には、ソフトウェアを構築するときに可能性に対処しないことを好みます」。私たちは皆それを好むと思います。そのため、メモリ内のデータストアに依存するシステムを構築することは決して失敗しないので、その可能性はかなり高いようです。他の点については、redisインスタンスを常にシャットオフできる攻撃者がいる場合、その解決策はおそらくJWTの使用を伴う必要はありません。
quietContest

@quietContestが一貫しているか、一生に一度のイベントかは、この点では同じです。つまり、適切に配置されたDDoS攻撃により、サーバーが「ユーザーをログアウト」させる可能性があります。これは、ソフトウェアの信頼性の評判にはうまくいきません。とにかく、redisはセッション管理には過剰だと思います。これはコストがかかり、スケーリングする必要がありますが、(安全に)JWTをCookieに保存することはしません。
Eyal Perry

1
@quietContest入力をありがとう、ディスカッションが大好きです!
Eyal Perry

0

ユーザー認証のためにJWTとトークン+キャッシュのどちらかを選択する同様の質問がありました。

これらの記事を読んだ後、JWTが約束する利点がJWTがもたらす問題を追い越さないことは私には明らかです。したがって、token + cache(Redis / Memcached)が私にとっての道です。

認証ヘッダーvs JWT vsセッション— APIに適切な認証技術を選択する方法

APIの認証手法

セッションでのjwtの使用を停止する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.