なぜ JWT はほとんどの OAuth 2.0 サービスで使われるのか
この記事では、なぜ JWT が OAuth 2.0 のアクセストークンの形式として広く採用されているのか、その利点と欠点を強調して解説します。
OAuth 2.0 は今日広く使用されています。認証サービスのコアフレームワークとして、OAuth 2.0 の主な責任の 1 つは、ユーザーのアクセストークンを発行することです。我々は、市場の多くの OAuth サービスプロバイダーが JWT 形式でアクセストークンを発行していることに気づきました。
この記事では、JWT が何であるか、OAuth 2.0 によって発行されるアクセストークンの形式として広く採用されている理由を紹介します。
JWT の紹介
JWT は JSON Web Token の略であり、RFC 7519 によって以下のように定義されています:
JSON Web Token (JWT) は、二つの当事者間で転送されるクレームを表現するためのコンパクトで、URL セーフな手段です。
この定義からわかるように、JWT は異なる当事者間でクレームを渡すために使用されるトークンです。
JWT は複数の当事者間で渡されるため、データの完全性と真正性を保証するために署名されています。
署名された JWT は次の形式を持ちます:
それは .
で区切られた 3 つの部分、ヘッダー、ペイロード、署名で構成されています。
こちらは現実世界での JWT の例です:
あなたはこれを https://jwt.io で解析してみることができます:
画像に示すように、JWT の header
セクションには使用された署名アルゴリズムとトークンのタイプに関する情報が含まれています。payload
セクションには JWT によって運ばれるクレームが含まれ、signature
は JWT の完全性を検証するために使用されます。
JWT が何であるか、そのさまざまな部分の意味を理解したので、なぜ多くの OAuth 認証サービスが JWT をアクセストークンとして選択するのかを説明しましょう。
JWT を使用する利点
JWT と従来のランダム生成文字列ベースのトークンとの主な違いは、JWT が情報を運ぶことができ、デコードを通じて検証できることです。これらの違いが2つの重要な利点をもたらします:
- リソース効率:JWT はユーザーまたはセッションに関する情報を運ぶことができ、頻繁なデータベース検索の必要がありません。この効率性は、サービスのリソース消費を減少させることができます。
- 向上した可用性とスケーラビリティ:JWT はサーバーサイドのステート管理への依存を減少させます。これにより、サービスはよりステートレスになり、その可用性とスケーラビリティを向上させます。
従来のランダム文字列ベースのトークンを使用する場合、検証と認証の一般的なプロセスは次の通りです:
図に示されているように、システムが多くのユーザーと異なるリソースサーバーを持っている場合、認証サーバーへの多数のトークン検証要求が生じる可能性があります。
時間が経つにつれて、システムが成長するにつれて、認証サーバーは簡単にボトルネックになることができ、全体的なサービスの可用性にとって挑戦となります。
しかし、JWT が導入されると、検証プロセスは次のように変わります:
JWT がデコードを通じて検証できる特性のおかげで、リソースサーバーは、認証サーバーと対話する必要なく、JWT の完全性を検証し、ユーザー情報を抽出することができます(JWT のデコードと検証の詳細については、Logto のドキュメント を参照してください)。
JWT の制限
JWT は現代のソフトウェアアーキテクチャにおいて重要な利点を提供しますが、考慮すべき制限も存在します。
簡単に覗かれるペイロード
先に述べたように、JWT は 3 つの部分で構成されています:header
、payload
、signature
。これらのコンポーネントはどのように生成されるのでしょうか?前の例から JWT の生成プロセスを示しましょう:
上のコードに示されているように、JWT のヘッダーとペイロードは単に base64 文字列としてエンコードされています。
これは、誰かがトークンにアクセスすることで簡単に JWT ペイロードの base64 文字列をデコードし、その情報にアクセスできることを意味します。逆に、ペイロードを比較的簡単に偽造し、元の JWT のペイロードを操作されたものに置き換えることも可能です。
JWT のペイロードは比較的簡単に偽造される可能性がありますが、JWT の署名部分を偽造された内容で置き換えることはできません。それは秘密の署名キーを必要とするからです。したがって、正しい署名がないと、JWT は検証に合格できません。
したがって、JWT を使用する際には以下の事項を考慮することが重要です:
- 常に SSL を使用する:JWT 情報が転送中に漏洩しないようにするために、SSL (Secure Sockets Layer) またはその後継である TLS (Transport Layer Security) を使用してデータを暗号化することが重要です。
- 機密データの格納を避ける:JWT ペイロードに機密データを格納することは推奨されません。前述のように、ペイロードは簡単にデコードでき、主に機密性の低い関連するクレームを含めるべきです。
- JWT を検証:JWT 内の情報に依存する前に、それが有効で安全な検証プロセスに合格したことを確認してください。署名の検証およびトークンの有効期限の確認を含みます。これにより、改ざんされたまたは不正なトークンの使用を防止します。
無効化が難しい
一般的に、アクセストークンは通常、有効期限を持っています。アクセストークンが情報を含まないランダム文字列で表現される場合、トークンが無効化されたかどうかを認証サーバーでの各検証中に確認できます。
JWT の場合、JWT 自体が有効期限情報を含み、JWT の検証が認証サーバーに依存しないため、認証サーバーが JWT 形式でアクセストークンを発行すると、その使用中にトークンの状態を変更することが不可能です。
JWT トークンが自然に期限切れになると、リフレッシュトークンを使用して認証サーバーから新しい JWT を取得できます(リフレッシュトークンに関する情報は Logto のブログ を参照してください)。
しかし、ユーザーが認可を取り消したり、パスワードを変更したりして、すでに発行されたがまだ期限切れしていないトークンを無効化する必要がある場合には、簡単な解決策はありません。
途中でのトークン無効化の影響を緩和するための一般的なアプローチが2つあります:
- アクセストークンの有効期限を短くし、トークンリフレッシュメカニズムに依存してトークンの状態を迅速に更新する。
アクセストークンが短い有効期限を持っているため、ユーザーがアクセストークンの期限切れを発見したときに、リフレッシュトークンを使用して認証サービスから新しいアクセストークンを要求できます。このようにして、ユーザー側のトークンの状態をバックエンドとできるだけ速く同期することができます。ただし、このアプローチには、ユーザーが考慮する必要がある追加のオーバーヘッドが伴います。
- アクセストークンの無効リストを維持し、各検証時にトークンがリストに載っているかどうかをチェックする。
この方法には一定の制限があります。JWT の利点の 1 つは、サーバーが状態情報を保存する必要がないことであり、JWT は基本的にステートレスです。しかし、無効リストを維持することは、効果的なストレージとメンテナンスを必要とし、追加のストレージメカニズムに依存します。これでは、JWT の利点を犠牲にし、潜在的にパフォーマンスの問題を引き起こす可能性があります。したがって、トークン無効化のメカニズムは、特定のユースケースに適した方法で開発者によって実装する必要があります。
まとめ
この記事では、JWT を簡単に紹介し、その利点と制限事項を強調しました。あなたは現在、JWT と、どのようなシナリオでよく使用されるかについて深く理解しているはずです。JWT にはその課題がありますが、OAuth 2.0 サービスにおけるトークン形式として使用された際の利点は、その欠点をはるかに上回ります。
Logto は急速に成長しているアイデンティティ認証サービスとしても JWT をそのアクセストークンの形式として採用しており、さまざまな認可および認証プロトコルを厳格に遵守し、製品にアイデンティティ認証サービスを統合するのを非常に容易にしています。Logto は公式に SaaS サービスを開始しており、今日から無料で試すことができます。