web-dev-qa-db-ja.com

JWTペイロードに情報を格納する

現在、アクセストークンは15分で有効期限が切れ、ペイロードに保存される情報はユーザーIDのみです。

各ユーザーは、アプリ内で使用できるバランスを持っています。バランスをプルできるように、リクエストごとにデータベースをクエリする必要がありますか?ペイロードを格納するのは安全ではないでしょうか?

17
civ15

tl/dr:残高をJWTに保存でき、改ざんから安全ですが、JWTの残高には多くの方法があります技術的には有効かもしれませんが、それでも正しくありません。したがって、おそらくデータベースの残高を毎回確認することをお勧めします。トランザクションを行う前に確認する必要があります。

JWTには次の2種類があります。

  1. JWS:ペイロードは「プレーンテキスト」であり、その内容を確認するための署名があります
  2. JWE:ペイロードは完全に暗号化されています。

これらは少し異なるユースケースを持っています。 JWTに格納されているデータが正しいこと、および改ざんされていないことを確認するだけでよい場合は、JWSで問題ありません(適切に実装し、すべてのリクエストの署名を確認するとします)。したがって、残高をJWSに保存し、報告された残高が最初に保存したものであることを後で確認できます。

データもプライベートにしたい場合は、JWEを使用できます。暗号化は、データが変更されないことも保証します(ここでも、JWEが適切に実装されていると想定しています)。通常はJWTにアクセスできるのはエンドユーザーだけなので、JWTを非公開にすることについて話していることに注意してください-おそらくユースケースでは必要ありません(h/t EdC )。

したがって、天びんは改ざんから安全です

どちらの場合でも、実際のトランザクションを行う前に、データベースとの残高を確認する必要があります。

残高がまだ間違っている可能性があります。JWTを更新せずに別のトランザクションが行われた場合、または古いJWTが提示された場合(別名リプレイ攻撃)、バランスが正しくない有効なJWTを使用できます。これは、アクティブな攻撃者がいなくても非常に可能性が高いです。複数のアプリを使用しているユーザーについて考えます。架空のシナリオで、あるデバイスのJWTに残高が保存され、ユーザーが別のデバイスにログインしてトランザクションを実行するとどうなりますか? JWT自体は有効で期限が切れていなくても、最初のデバイスのJWTのデータは正しくありません。これは、有効だが不正なJWTが発生する可能性がある多くの方法の1つにすぎません。

JWTの古いデータの問題を修正する方法は数多くありますが、結局のところ、これらの修正は、データベースを毎回チェックするよりも作業が増える可能性があります。しかし、それは最終的にあなた次第であるバランスのとれた行為です!正解は1つではありません。

30
Conor Mancone

はい、リクエストごとにデータベースをクエリする必要があります。 JWTアプローチを使用するということは、正しいJWTを送信するためにクライアントに依存していることを意味します。 JWTにバランスを保存することを提案している場合は、バランスが変更されるたびに新しいJWTを生成することをお勧めします。問題は、クライアントを信頼して正しいJWTを送信することです。

  • 00:00-アプリにアクセスします。 JWTは、残高($ 10)と15分の存続時間で生成されます。これを「トークン1」と呼びましょう。
  • 00:05-5ドルで購入します。これにより、おそらくサーバーは残高が5ドルの新しいJWTを生成します。これを「トークン2」と呼びましょう。
  • 00:10-$ 10の購入を試みます。しかし、私は(トークン2ではなく)トークン1を送信するようにアプリを変更しました。それはまだ効果的で、10ドルの残高があります。データベースをチェックせずに、トランザクションが完了しないのはなぜですか?
18
Andy N

リクエストごとにデータベースにクエリを実行すると、JWTを使用することの主な利点が失われます-データベースにアクセスする必要がないということです。あなたが JWTを正しく使用している であると仮定すると、その中に情報を保存しても安全です。署名されているため、攻撃者はコンテンツをいじることはできません。

編集:署名はペイロードが改ざんされていないことを確認しますとはいえ、それがまだ最新であることを保証するものではありません。参照してください Andy Nの非常に良い答え

4
Anders