cover

JWTに関するいくつかの考察

sorcererxw

このセクションは翻訳対象ではありません。

Json Web Token(略称JWT)は認証方式の一つで、従来のSession方式と異なり、JWTはサーバー側でユーザーのログイン状態を保存する必要がなく、ステートレスであることを選択し、状態を非対称暗号化してToken内に保存します。ユーザーはこのTokenを使用して各種リソースにアクセスできます。

このステートレス認証方式は、マイクロサービスの流行と共に、ますます多く使用されるようになりました。これにより、バックエンドの各種リソースサービスと認証サービスをデカップリングすることができます。リソースサーバーは、ゲートウェイやミドルウェアによって解析されたユーザー情報を受け取り、この情報に基づいて対応する操作を行うだけで済みます。

考察

なぜAccessTokenとRefreshTokenの組み合わせを使用するのでしょうか?

単にAccessTokenを使用して認証と更新を実現することも可能ですが、その一般的な方法は、AccessTokenにaccess_expire_timeoutrefresh_expire_timeoutの2つの時間を含めて、このトークンで行える操作を示します。しかし、この方法にはセキュリティ上の問題が存在します。それは、トークンが選手でありながら審判でもあるようなもので、リソースへのアクセスと更新の両方が可能であり、一度このトークンが漏洩した場合、そのトークンに対する制限を加えることが非常に困難です。

アクセスリソースとトークンをリフレッシュする二つの権限をアクセストークンリフレッシュトークンに分けて権限を隔離することで、ある程度の安全性を保証します。

  • もしAccessTokenが漏洩したとしても、AccessTokenの短い有効期限(数十分)のため、大きな影響は生じないでしょう。
  • もしRefreshTokenが漏洩した場合でも、リフレッシュ時にデバイス情報を添える必要があるため、第三者が不正に使用することは困難です。

AccessTokenとRefreshTokenにはどのような情報を含めるべきでしょうか?

RefreshTokenとAccessTokenは同じくJWTですが、有効期限や含まれる情報量が異なります。

RefreshTokenは基本的なユーザーIDとデバイスIDのみを含める必要があり、リフレッシュ時に対応するデバイスを特定できるようにすることが保証されています。

それに応じて、RefreshTokenもこれらの情報のみを保持することができますが、不必要な他のサービスへのリクエストを防ぐために、より多くの冗長な情報を保持することができます。

AccessTokenとRefreshTokenは異なるKeyPairを使用する必要がありますか?

もしAccessTokenとRefreshTokenが同じキーセットで解読できる場合、そしてAccessTokenとRefreshTokenが似たような情報を含んでいる場合、ユーザーはRefreshTokenをAccessTokenとして使用してアクセスすることができ、有効期限の問題を心配する必要がありません。これはかなりのセキュリティ問題を引き起こす可能性があります。

解決策は異なるキーを使用して暗号化・復号化を行い、二つのトークンが互いに置き換え可能でないことを保証することです。

トークンのグループをブラックリストに登録する方法は?

JWTを使用する一つの目的は、サーバー側でユーザーのトークンを保存する必要がないことです。そのため、ユーザーやデバイスをブラックリストに入れたい場合でも、そのユーザーやデバイスに対応するトークンを知る術がありません。もちろん、グローバルなユーザーブラックリストを作成し、リソースへのアクセスの度にチェックを行うことも可能ですが、これはリソースサーバーがユーザー認証を操作する必要がないという設計原則に反しています。

もちろん、RefreshTokenの観点から処理することもできます。Refresh操作は頻繁に行われるわけではありませんが、AccessTokenの有効期限が比較的短いため、Refresh操作は短い時間ごとに一度行われます。その際、RefreshTokenに含まれるユーザー情報やデバイス情報を基にして、Refreshを許可するかどうかを判断することで、リソースサーバーに負担をかけることはありません。

零遅延で強制ログアウトを実現するには?

上述のブラックリスト方式によると、オフラインにする最長遅延はAccessTokenの有効期限になります。もし機密情報に関わる場合、危険なユーザーやデバイスを即座にオフラインにすることは難しいです。

Appの冷起動やウェブページの開設時にリフレッシュを行うことで、被害を可能な限り減少させることができます。しかし、それでも要求を十分に満たすことはできません。

私たちが普段目にするGoogleやTelegramのようなセキュリティセンターでは、全てのデバイスリストが表示され、特定のデバイスを即座にログアウトさせる選択ができます。もし仮にこの製品がOAuthを使用している場合、これはどのように実現されているのでしょうか?

推測される操作プロセス:

  • 対応するデバイスをブラックリストに入れる
  • デバイスがオンラインの場合、通知プッシュを通じてリフレッシュを要求するか、直接オフラインにすることができます。(ただし、これはまた別の話題ですが)
  • デバイスがオフラインの場合、次回起動時にリフレッシュを実行することで、ログオフを実現できます。