RESTful APIでのトークン更新/セッション有効期限の処理


17

ユーザー認証にJWTトークンを使用するRESTful APIを構築しています(loginエンドポイントによって発行され、その後すべてのヘッダーで送信されます)。一定時間後にトークンを更新する必要がありrenewます(エンドポイントを呼び出して、更新されたトークンを返します) )。

トークンの有効期限が切れる前にユーザーのAPIセッションが無効になる可能性があるため、エンドポイントはすべて、1)トークンがまだ有効で、2)ユーザーのセッションがまだ有効であることを確認することから開始します。クライアントがトークンをローカルに保存するため、トークンを直接無効にする方法はありません。

したがって、すべてのエンドポイントは、クライアントに次の2つの条件を通知する必要があります。1)トークンを更新する時間、または2)セッションが無効になり、システムへのアクセスが許可されなくなったこと。2つの条件のいずれかが発生したときにクライアントに信号を送るエンドポイントの2つの代替案を考えることができます(クライアントがいずれかのオプションに適応できると仮定します):

  1. セッションが無効になった場合はHTTP 401コード(無許可)を返し、トークンの有効期限が切れてrenewエンドポイントを呼び出すときは412コード(前提条件失敗)を返します。これにより200(ok)コードが返されます。
  2. セッションが無効であるか、トークンの有効期限が切れていることを通知するために401を返します。この場合、クライアントはすぐにrenewエンドポイントを呼び出し、200を返すとトークンが更新されますが、renew401も返す場合は、クライアントがシステム外にあることを意味します。

上記の2つの選択肢のうち、どちらをお勧めしますか?どちらがより標準的で、理解しやすく、そして/またはよりRESTfulでしょうか?または、まったく別のアプローチをお勧めしますか?どちらのオプションにも明らかな問題やセキュリティ上のリスクがありますか?回答にあなたの意見を裏付ける外部参照が含まれている場合の追加ポイント。

更新

皆さん、本当の質問に焦点を合わせてください- 更新/セッションの無効化を通知するための2つのHTTPコードの選択肢のうち、どちらが最適ですか?私のシステムがJWT サーバーサイドセッションを使用しているという事実を気にしないでください、それは非常に特定のビジネスルールのための私のAPIの特性であり、私が助けを求めている部分ではありません;)


短い(約5分)有効期限を想定して、トークンの有効期限が切れる前にユーザーのセッションはどのように無効になりますか?
ジャック

ビジネスルールにより、システムの別の部分がセッションを無効にする場合があります。
オスカーロペス

1
JWTは、「このリクエストはユーザーXからのものであることが証明されています」のように、IDの証明用です。ビジネスルールが「ユーザーXがリソースYと対話することを許可されなくなった」などの場合、JWTとは別にチェックする必要があります。
ジャック

まさにジャック!それが正確に私のポイントであり、セッション情報を保存するために追加のステートフルレイヤーを使用する必要がある理由です。平易なJWTは、それがいいかもしれませんが、仕事のためにカットされていないだけです。
オスカーロペス

1
あなたは私の答えに興味があるかもしれません:)
ジャック

回答:


22

これは、認証認可の場合のように聞こえます。

JWTは、要求の発信者に関する暗号で署名されたクレームです。JWTには、「このリクエストはユーザーX向けです」や「ユーザーXには管理者ロールがあります」などのクレームが含まれる場合があります。パスワード、署名、およびTLSを介してこの証明を取得して提供することは、認証のドメインです-自分が本人であることを証明します。

サーバーにとってこれらの主張が意味するもの、つまり特定のユーザーと役割が許可されていることは、承認の問題です。この2つの違いは、2つのシナリオで説明できます。ボブが会社の倉庫の保管制限区域に入ることを望んでいるが、最初にジムという警備員に対処しなければならないとします。

シナリオA-認証

  • ボブ:「こんにちは、ジム、制限付き保管庫に入れたいです。」
  • ジム:「バッジを持っていますか?」
  • ボブ:「いや、忘れた」
  • ジム:「ごめんなさい、バッジなしのエントリーはありません。」

シナリオB-承認

  • ボブ:「こんにちは、ジム、制限された保管場所に入りたいのですが、これが私のバッジです。」
  • ジム:「ボブ、ここに入るにはレベル2のクリアランスが必要です。ごめんなさい。」

JWTの有効期限は、他人が盗み出すことを防ぐために使用される認証デバイスです。すべてのJWTの有効期限が5分の場合、盗まれてもすぐに役に立たなくなるため、それほど大した問題ではありません。ただし、説明する「セッションの有効期限」ルールは、認証の問題のように聞こえます。状態の変化は、ユーザーXが以前はできることを実行できなくなったことを意味します。たとえば、ユーザーBobが解雇された可能性があります。Bobであるということは、Bobであるだけで会社に対する権限が与えられなくなるためです。

これらの2つのケースには、異なるHTTP応答コードが401 Unauthorizedあり403 Forbiddenます。残念ながら401コードという名前は、資格情報の欠落、期限切れ、失効などの認証の問題のためのものです。403は承認のためのもので、サーバーはあなたが誰であるかを正確に知っていますが、あなたがしようとしていることを行うことは許可されていません。ユーザーのアカウントが削除されている場合、エンドポイントでJWTで何かを行おうとすると、403 Forbidden応答が返されます。ただし、JWTの有効期限が切れている場合、正しい結果は401 Unauthorizedになります。

一般的なJWTパターンは、「長命」および「短命」のトークンを持つことです。長期トークンは短期トークンのようにクライアントに保存されますが、範囲が制限されており、短期トークンを取得するために認証システムでのみ使用されます。名前が示すように、長寿命のトークンは非常に長い有効期限があります-それらを使用して、何日または何週間も新しいトークンをリクエストできます。短期トークンは、説明しているトークンであり、非常に短い有効期限でシステムと対話するために使用されます。存続期間の長いトークンは、Remember Me機能を実装するのに便利です。したがって、新しい短命のトークンを取得するために5分ごとにパスワードを入力する必要はありません。

あなたが説明している「セッション無効化」問題は、寿命の長いJWTを無効にしようとするのと似ています。そのようなシステムでは、ユーザーは技術的に資格情報を取得できるかもしれませんが、使用しているトークンはタスクに適していないため、取り消された長期間有効なトークンで資格情報を取得しようとすると401 Unauthorizedになります。その後、ユーザーがユーザー名とパスワードを使用して新しい長期トークンを取得しようとすると、システムから追い出された場合、システムは403 Forbiddenで応答する可能性があります。


3
これは私が探していたガイダンスであり、非常に関連性の高い洞察を議論にもたらしました-これは認証と認可の場合であり、それぞれ異なる方法で対処する必要があるということです。ありがとう!
オスカーロペス

16

APIセッションは、RESTfulの世界に存在すべきではないものです。RESTful操作はステートレスであると想定されており、セッションには状態が含まれているため、RESTfulの世界には場所がありません。

JWTは、ユーザーがエンドポイントにアクセスする資格があるかどうかを判断する唯一の方法です。セッションは絶対に役割を果たさないはずです。存在する場合、RESTful APIはありません。

セッションを完全に削除すると、RESTful APIを目指している場合にJWTのみを認証要素として使用し、ユーザーはエンドポイントの使用を許可されるかどうかを決定します。この場合、401 Unauthorized応答コードは適切です。 - renewエンドポイントをgrant_type=refresh_token使用して、更新の識別情報を呼び出す必要があります。

更新:

コメントから、現在使用しているJWTの検証フローが正しくないようです。検証は次のようになります。

  Client        RESTful API      JWT Issuer
     |              |                |
     |----- 1. ---->|                | 
     |              |------ 2. ----->|-----
     |              |                | 3. |
     |              |<----- 4. ------|<----
-----|<---- 5. -----|                |
| 6. |              |                |
---->|----- 7. ---->|                |
     |              |------ 8. ----->|-----
     |              |                | 9. |
     |              |<----- 10. -----|<----
     |              |                |
     |              |------          |
     |              | 11. |          |
     |<---- 12. ----|<-----          |
     |              |                |
     .              .                .

1. Ask RESTful API for a JWT using login endpoint.
2. Ask Issuer to create a new JWT.
3. Create JWT.
4. Return JWT to the RESTful API.
5. Return JWT to Client.
6. Store JWT to append it to all future API requests.
7. Ask for data from API providing JWT as authorization.
8. Send JWT to Issuer for verification.
9. Issuer verifies JWT.
10. Issuer returns 200 OK, verification successful.
11. Retrieve and format data for Client.
12. Return data to Client.

サーバーはRESTful API、承認として送信されているトークンの有効性を確認する必要があります。それはの責任ではありませんClient。現在、これを行っていないようです。この方法でJWTの検証を実装すると、セッションはまったく必要ありません。


ご回答有難うございます。セッションを使用することは100%RESTfulなアプローチではないことに同意しましたが、前述したように、トークンの有効期限が切れる前に一部のユーザーへのアクセスを拒否する必要があります。
オスカーロペス

2
@ÓscarLópez次に、ユーザーが使用しているトークンを無効にします。提供されたトークン(無効になります)を使用してAPIにアクセスできなくなり、セッションは必要ありません。
アンディ

1
トークンはクライアントに保存されますが、そこでトークンを無効にするにはどうすればよいですか?どれが有効であるかを追跡する必要があります...そして、それは状態がそのい頭を育てる場所です。避けられないこともあります。
オスカーロペス

悪意のあるクライアントは、有効期限が許す限り以前の有効なトークンを送信し続けることができますが、すぐにシステムから追い出す必要があります-したがって、短い更新時間を設定することもオプションではありません。
オスカーロペス

4
@Laivメモ帳でシーケンス図を作成しました。
アンディ

1

したがって、セッションで既にRESTの規則を破っているときに、どのアプローチが最もRESTfulであるかを心配することはあまり意味がありませんが、ビジネス要件を満たすことは理解できます。

RESTの観点から、クライアントは認証されるか、認証されません。アーキテクチャはなぜ(それが不必要な状態を注入するのか)あまり気にしないので、あなたの主な質問に答えるために、私はまったく新しいエンドポイントを持っていません。ログインしたクライアントは常にJWTを送信し、サーバーは常にJWTを検証し、アクション200、201などに基づいて適切な成功コードを送信して受け入れるか、必要に応じて401または403で拒否します。

これで、JWTが何らかのアカウントに関連付けられます。そのアカウントはロックされているか、スロットルされているか、または何であれ、トークン自体は有効であるが、アクションは他の場所で拒否されます。ビジネスルールのためにユーザーアカウントがロックされている場合は、クライアントに提供する情報量に応じて401または403になります(ビジネスごとに意見が異なります)。

最後に、アカウントがロック解除され有効であってもJWTを取り消すだけでよいと断言している場合は、401または403をそのまま使用し、無効なJWTの証明書失効リストなどを維持します。 、JWTが期限切れになったときに自動的にクリーンアップする限り(ほとんどのデータベースにはそれを行う方法があるか、アプリのコードにイベントを含めることができます)。


jwtはステートレスであることを意図しています。その内容に疑問を
投げ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.