78

JWT でのリフレッシュ トークンの使用について説明している別の SO 投稿を参照しています。

JWT(JSON Web Token)の自動有効期限延長

クライアント (Web およびモバイル) が REST API と対話し、サービス層とデータ層と対話する、非常に一般的なアーキテクチャのアプリケーションがあります。

ここに画像の説明を入力

JWT トークン認証については理解していますが、リフレッシュ トークンの使用方法について少し混乱しています。

JWT 認証に次のプロパティを持たせたい:

  1. JWT トークンの有効期限は 2 時間です。

  2. トークンは、クライアントによって 1 時間ごとに更新されます。

  3. ユーザー トークンが更新されず (ユーザーが非アクティブで、アプリが開いていない)、有効期限が切れた場合、再開するたびにログインする必要があります。

リフレッシュ トークンの概念を使用してこれをより良いエクスペリエンスにすると主張する人がたくさんいますが、これの利点はわかりません。それを管理しなければならないのは、追加の複雑さのようです。

私の質問は次のとおりです。

  1. リフレッシュ トークンを使用する場合、そのトークンの有効期限を長期に設定することは有益ではないでしょうか?
  2. リフレッシュ トークンを使用する場合、そのトークンは userId および/または JWT トークンと共に永続化されますか?
  3. トークンを 1 時間ごとに更新すると、どのように機能しますか? JWT トークンまたはリフレッシュ トークンを受け取るエンドポイントを作成しますか? これにより、元の JWT トークンの有効期限が更新されますか、それとも新しいトークンが作成されますか?
  4. これらの詳細を考えると、更新トークンは必要ですか? ユーザーが JWT トークンを使用して新しいトークンを取得しているだけの場合 (上記のリンクに従って)、更新トークンは廃止されているようです。
4

3 に答える 3

175

少し後であなたの質問に答えて、リフレッシュトークンの目的全体について実際に議論することから始めましょう.

したがって、状況は次のとおりです。

ユーザーはアプリを開き、ログイン資格情報を提供します。現在、おそらくアプリは REST バックエンド サービスと対話しています。REST はステートレスであるため、API へのアクセスを承認する方法はありません。したがって、これまでの説明では、許可されたユーザーが API にアクセスしているかどうか、またはランダムなリクエストが送信されているだけかどうかを確認する方法はありません。

この問題を解決するには、リクエストが許可されたユーザーからのものであることを知る方法が必要です。そこで、アクセストークンと呼ばれるものを導入しました。したがって、ユーザーが正常に認証されると、アクセス トークンが発行されます。このトークンは、長くて非常にランダムなトークンである必要があります (推測できないようにするため)。ここで JWT の出番です。現在、ユーザー固有の詳細を JWT トークンに保存したい場合としない場合があります。理想的には、非常に単純で機密性の低い詳細を JWT に保存するだけです。他のユーザーの詳細 (IDOR など) を取得するための JWT ハッシュの操作は、JWT (使用されているライブラリ) 自体によって処理されます。

したがって、今のところ、承認されたアクセスに関する問題は解決されています。

次に、攻撃シナリオについて説明します。上記のすべてのユーザー Alice を使用して、アプリを使用し、承認されたアクセス トークンを持っているとします。これで、彼女のアプリはすべての API にリクエストを送信し、彼女の承認に従ってデータを取得できます。

何らかの形で Alice が Access Tokenを紛失した、または別の言い方をすれば、敵対者 Bob が Alice の Access Token にアクセスしたとします。これで、Bob は許可されていませんが、Alice が許可されていたすべての API に対してリクエストを行うことができます。

理想的には望まないもの。

この問題の解決策は次のとおりです。

  1. この種の何かが起こっていることを検出します。
  2. 攻撃ウィンドウ自体を減らします。

アクセス トークンだけを使用すると、上記の条件 1 を達成するのは困難です。なぜなら、Alice であれ Bob であれ、同じ承認済みトークンが使用されているため、2 人のユーザーからの要求を区別できないからです。

したがって、上記の 2 を達成しようとするため、アクセス トークンの有効期限に有効期限を追加します。たとえば、アクセス トークンは 't' (短期間) 有効です。

それはどのように役立ちますか?ボブはアクセス トークンを持っていても、それが有効な間だけ使用できます。有効期限が切れるとすぐに、彼はそれを再度取得する必要があります。もちろん、彼は最初に手に入れたのと同じ方法でそれを手に入れることができると言えます。しかし、100% のセキュリティに勝るものはありません。

上記のアプローチにはまだ問題があり、場合によっては受け入れられません。アクセス トークンの有効期限が切れると、ユーザーは自分のログイン資格情報を入力し、承認されたアクセス トークンを再度取得する必要があります。これは、少なくともモバイル アプリの場合、ユーザー エクスペリエンスが悪い (受け入れられない) ものです。

解決策:ここでリフレッシュ トークンの出番です。これもランダムで予測不可能なトークンであり、最初にアクセス トークンと共にアプリにも発行されます。この更新トークンは非常に有効期間の長い特別なトークンであり、アクセス トークンの有効期限が切れるとすぐにサーバーに新しいアクセス トークンを要求するため、ユーザーがログイン資格情報を再入力して取得する必要がなくなります。既存のトークンの有効期限が切れると、新しい承認済みアクセス トークン。

ボブは、アクセス トークンを侵害したのと同じように、リフレッシュ トークンにもアクセスできると思うかもしれません。はい。彼はできます。しかし、アクセス トークンだけでは不可能だったそのような発生を特定し、被害を軽減するために必要な措置を講じることが容易になりました。

どのように?

認証されたユーザーごとに (通常、モバイル アプリの場合)、1 対 1 でマップされた更新トークンとアクセス トークンのペアがアプリに発行されます。そのため、任意の時点で、認証された 1 人のユーザーに対して、更新トークンに対応するアクセス トークンは 1 つだけです。ここで、Bob が更新トークンを侵害した場合、彼はそれを使用してアクセス トークンを生成すると仮定します (アクセス トークンは、API を介してリソースにアクセスすることを許可されている唯一のものであるため)。ボブ (攻撃者) が新しく生成されたアクセス トークンを要求するとすぐに、アリス (本物のユーザー) のアクセス トークンがまだ有効であるため、サーバーはこれを異常と見なします。時間。異常を特定すると、サーバーは問題のリフレッシュ トークンを破棄し、それとともに、関連付けられているアクセス トークンも無効になります。したがって、リソースを必要とする承認への、本物または悪意のあるアクセスを防止します。ユーザーの Alice は、資格情報を使用してもう一度認証し、有効な更新トークンとアクセス トークンのペアを取得する必要があります。

もちろん、Bob が再びリフレッシュ トークンとアクセス トークンの両方へのアクセスを取得し、上記のすべての話を繰り返し、実際の真の顧客である Alice に対する DoS につながる可能性があると主張することもできますが、100% のセキュリティに勝るものはありません。 .

また、良い方法として、更新トークンには有効期限がありますが、かなり長いものです。

于 2016-03-29T09:38:10.857 に答える
20

このシナリオでは、アクセス トークンだけを使用して、クライアントの作業を楽にし、更新トークンのセキュリティ上の利点を維持できると思います。

これがどのように機能するかです:

  1. ユーザーが資格情報 (ユーザー名/パスワード) でログインすると、有効期間の短い JWT が返されます。また、以下を格納する db レコードを作成します。

    • JWT ID
    • ユーザーID
    • IPアドレス
    • ユーザーエージェント
    • validフラグ (デフォルトは TRUE )
    • 作成日時
    • 更新日時
  2. クライアントはすべてのリクエストで JWT を送信します。JWT の有効期限が切れていない限り、リソースにアクセスできます。JWT の有効期限が切れた場合は、バックグラウンドで更新X-JWTし、新しい JWT を使用してリソースと追加のヘッダーの両方を返します。

  3. クライアントがX-JWTヘッダー付きの応答を受信すると、古い JWT を破棄し、今後の要求に新しい JWT を使用します。

サーバー上での JWT の更新のしくみ

  1. JWT ID を使用して、一致する db レコードを探します。
  2. validフラグがまだ trueかどうかを確認し、そうでない場合は拒否します。
  3. 必要に応じて、リクエストの IP アドレスとユーザー エージェントを保存されている IP アドレスとユーザー エージェントと比較し、怪しいものがある場合は拒否することを決定できます。
  4. 必要に応じて、db レコードの createdAt フィールドまたは updatedAt フィールドを確認し、時間が経過しすぎた場合は更新しないことを決定できます。
  5. updatedAtdb レコードのフィールドを更新します。
  6. 新しい JWT を返します (これは基本的に期限切れの JWT のコピーですが、有効期限が延長されています)。

この設計では、ユーザーのすべてのトークンを取り消すオプションも提供されます (たとえば、ユーザーが電話を紛失したり、パスワードを更新した場合)。

利点:

  • クライアントは、有効期限を確認したり、トークンの更新を要求したりする必要はありませんX-JWT。応答のヘッダーを確認するだけです。
  • IP アドレス、ユーザー エージェント、最大トークン期間、またはそれらの組み合わせに基づいて、カスタムの更新ロジックを追加できます。
  • ユーザーの一部またはすべてのトークンを取り消すことができます。
于 2016-12-20T19:42:48.070 に答える