すべてのプロダクト
Search
ドキュメントセンター

API Gateway:JWT-logout

最終更新日:Sep 10, 2026

jwt-logout プラグインは、Redis を使用して JSON Web Token (JWT) の弱い状態管理を実装し、JWT の事前無効化と単一デバイスログイン制御を可能にします。たとえば、ユーザーが新しいデバイスからログインすると、以前のセッションは自動的に無効化されます。

プラグインのタイプ

認証および権限付与のためのプラグインです。

フィールド

フィールド

データ型

必須

デフォルト値

説明

jwks

string

いいえ

-

JWT 検証用の JSON 文字列。このプラグインを jwt-auth プラグインと共に使用する場合は不要です。詳細については、「JSON Web Key (JWK)」をご参照ください。

clock_skew

数値

いいえ

60

JWT の exp および iat フィールドを検証する際に許容されるクロックスキュー。単位: 秒。

token_header

string

いいえ

Authorization

JWT を抽出するリクエストヘッダー。

token_prefix

string

いいえ

"Bearer"

ヘッダー値のプレフィックス。プレフィックスを削除した後、残りの部分が JWT として使用されます。

redis

Redis

はい

-

Redis サービスの設定。

logout

Logout

いいえ

-

JWT ログアウト機能の設定。設定しない場合、JWT ログアウトは無効になります。

login

Login

いいえ

-

JWT 単一デバイスログイン機能の設定。設定しない場合、単一デバイスログインは無効になります。

次の表は、Redis タイプの構成フィールドについて説明します。

フィールド

データ型

必須

デフォルト値

説明

service

string

はい

-

Redis サービスの名前。例:

  • 固定アドレス: my-redis.static

  • DNS ドメイン名: my-redis.dns

  • ACK: my-redis.default.svc.cluster.local

port

数値

はい

-

Redis サービスのポート番号。

username

string

いいえ

-

Redis の AUTH コマンドのユーザー名。

password

string

いいえ

-

Redis の AUTH コマンドのパスワード。

timeout

数値

いいえ

1000

Redis コマンドのタイムアウト期間。単位: ミリ秒。

次の表は、Logout タイプの構成フィールドについて説明します。

フィールド

データ型

必須

デフォルト値

説明

key_prefix

string

いいえ

higress_jwt_logout_

Redis に保存されているキーのプレフィックス。

key

文字列の配列

いいえ

["jti"]

JWT ペイロード内で、JWT を識別するためのキー。複数の JWT ペイロードに同じキーが出現する場合、それらの JWT は同一として扱われます。JWT ペイロードにキーが存在しない場合、401 invalid token エラーが返されます。

path

string

いいえ

/jwt_logout

URL パスのサフィックスと一致させるために使用される文字列。一致した場合、現在のリクエストの JWT は無効化され、使用できなくなります。

error_status

数値

いいえ

401

ログアウトした JWT が使用されたときに返される HTTP ステータスコード。

error_body

string

いいえ

'{"message":"invalid token"}'

ログアウトした JWT が使用されたときに返されるレスポンスボディ。

ttl

数値

いいえ

-

Redis に保存されているキーの有効期間 (TTL)。単位: 秒。ログアウト後に JWT が無効化された状態を維持する期間を決定します。指定しない場合、TTL はペイロードの exp フィールドの値から現在時刻を引いた値と等しくなります。ペイロードに exp フィールドが含まれていない場合、デフォルトの TTL は 86,400 秒 (24 時間) です。

次の表は、Login タイプの構成フィールドについて説明します。

フィールド

データ型

必須

デフォルト値

説明

key_prefix

string

いいえ

higress_jwt_login_

Redis に保存されているキーのプレフィックス。

key

文字列の配列

いいえ

["iss","aud","sub"]

JWT ペイロード内の単一デバイスログイン識別子。現在のリクエストの JWT に、以前に認証された JWT と同じフィールド値が含まれているが、完全に同じ JWT ではない場合、リクエストは重複ログインとして拒否されます。認証された JWT の Redis キーが期限切れになるまでアクセスは拒否されます。JWT ペイロードにフィールドが存在しない場合、401 invalid token エラーが返されます。

path

string

いいえ

/jwt_login

URL パスのサフィックスと一致させるために使用される文字列。一致した場合、現在のリクエストの JWT がアクティブなセッショントークンになり、同じペイロード特性を持つ以前に認証された JWT は無効化されます。

error_status

数値

いいえ

403

重複ログイン試行に対して返される HTTP ステータスコード。

error_body

string

いいえ

'{"message":"already login on other device"}'

重複ログイン試行に対して返されるレスポンスボディ。

ttl

数値

いいえ

-

Redis に保存されているキーの TTL。単位: 秒。単一デバイスログイン JWT の有効期間を決定します。指定しない場合、TTL はペイロードの exp フィールドの値から現在時刻を引いた値と等しくなります。ペイロードに exp フィールドが含まれていない場合、デフォルトの TTL は 86,400 秒 (24 時間) です。

設定例

ApsaraDB for Redis インスタンスの使用

  1. ApsaraDB for Redis インスタンスを作成します。詳細については、「概要」をご参照ください。

  2. ログアウトおよびログイン設定を有効にします。プラグインがリクエストを処理すると、ログアウト設定チェック用に Redis 読み取りリクエストが 1 回、ログイン設定チェック用に Redis 読み取りリクエストが 2 回生成されます。ログアウトや初回ログインなどのまれなケースでは、追加で Redis 書き込みリクエストが 2 回生成されます。ApsaraDB for Redis インスタンスの容量を見積もるには、プラグインが処理するリクエストのスループットに 2 を掛けます。

  3. ApsaraDB for Redis インスタンスを設定した後、インスタンスの VPC エンドポイントを取得します。例: r-xxxxxxx.redis.rds.aliyuncs.com。

  4. サービスを追加します。 [サービスソース] ドロップダウンリストから「DNS ドメイン名」を選択し、[サービスポート] フィールドに Redis ポート番号 (ほとんどの場合 6379) を入力し、[ドメイン名] フィールドに VPC エンドポイントを入力し、[TLS モード] ドロップダウンリストから [無効] を選択します。 詳細については、「サービスの作成」をご参照ください。

  5. ApsaraDB for Redis インスタンスに接続するために、プラグイン設定に次の内容を追加します:

    redis:
      service: redis.dns
      port: 6379

    Redis サービスにパスワードを設定する場合は、次の内容を追加します:

    redis:
      service: redis.dns
      port: 6379
      password: ****** # 指定したパスワードを入力します。

JWT ログアウト機能の実装

利用シーン

JWT はステートレスなトークンであり、有効期限が切れるまで有効です。jwt-logout プラグインを使用して、有効期限が切れる前に特定の JWT を強制的に無効化します。

仕組み

  • リクエストパスのサフィックスがプラグイン設定のパスと一致する場合、ログアウトメカニズムがトリガーされます。ApsaraDB for Redis インスタンスは、ログアウト用の JWT を記録します。ApsaraDB for Redis インスタンスに保存されるキーは、設定されたプレフィックスと、現在の JWT ペイロードから抽出されたキーと値で構成されます。

  • リクエストに含まれる JWT のペイロードが、ApsaraDB for Redis インスタンスに保存されているキーの特性と一致する場合、システムは現在の JWT を無効とみなし、リクエストを拒否します。

  • ApsaraDB for Redis インスタンスに保存されているキーのデフォルトの有効期限は、JWT ペイロードの exp フィールドに基づいて計算されます。つまり、キーは JWT が期限切れになるまで保存できます。

説明
  • プラグインのデフォルトで推奨されるログアウトキーは ["jti"] です。ここで、jti は JWT を一意に識別するペイロードフィールドです。JWT 標準で指定されているように、JWT ペイロードの jti 値が ApsaraDB for Redis インスタンスに記録されている値と同じ場合、JWT 全体が完全に同じになります。したがって、jti を使用して JWT のログアウト状態をマークできます。

  • ApsaraDB for Redis インスタンスに保存されるキーの連結ルール: <key_prefix><PayloadKey>##<PayloadValue>。PayloadKey はシャープ記号 (#) で区切られたキーのリストです。PayloadValue はシャープ記号 (#) で区切られたキー値のリストです。例: higress_jwt_logout_jti#iss##xxxxx#abcde。

  • このプラグインは、ログアウト中に現在のリクエストに含まれるトークンのみを無効化できます。前述のキー連結ルールに基づいて、ApsaraDB for Redis コンソールで手動でトークンを指定することもできます。ゲートウェイが ApsaraDB for Redis インスタンスにキーが存在することを検出した場合、ゲートウェイは関連する JWT に基づくアクセスリクエストを拒否します。

例

プラグイン設定:

redis:
  service: redis.dns
  port: 6379
jwks: |
  {
    "keys": [
      {
        "kty": "oct",
        "kid": "123",
        "k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
        "alg": "HS256"
      }
    ]
  }
logout:
  path: "/jwt_logout"
  key: ["jti"]
  error_status: 401
  error_body: |
    {"message":"invalid token"}
  1. ログアウトをトリガーします。

    curl  http://xxx.hello.com/test/jwt_logout -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJ4eHh4IiwiaXNzIjoiYWJjZCIsInN1YiI6InRlc3QiLCJhdWQiOiJ3d3cudGVzdC5jb20iLCJpYXQiOjE2NjU2NjA1MjcsImV4cCI6MTg2NTY3MzgxOX0.tmKF6qc1mOWNyCCzBOT2XKNoEGeEgr3EbhTKAQfq1io'
    
    # 次の結果が返されます:
    {"message": "logout success"}

    トークンペイロード:

    {
        "jti": "xxxx",
        "iss": "abcd",
        "sub": "test",
        "aud": "www.test.com",
        "iat": 1665660527,
        "exp": 1865673819
    }

    この場合、キー higress_jwt_logout_jti##xxxx は ApsaraDB for Redis インスタンスに保存されます。

  2. ログアウト後、JWT に基づくアクセスは許可されません。

    curl  http://xxx.hello.com/test/abc -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJ4eHh4IiwiaXNzIjoiYWJjZCIsInN1YiI6InRlc3QiLCJhdWQiOiJ3d3cudGVzdC5jb20iLCJpYXQiOjE2NjU2NjA1MjcsImV4cCI6MTg2NTY3MzgxOX0.tmKF6qc1mOWNyCCzBOT2XKNoEGeEgr3EbhTKAQfq1io'
    
    # 次の結果が返されます:
    {"message":"invalid token"}

JWT による単一デバイスログインの実装

利用シーン

アカウントが複数のデバイスから JWT 認証でログインする場合、デバイスごとに異なる JWT が発行されることがあります。jwt-logout プラグインを使用して単一デバイスログインを強制し、一度に 1 つのセッションのみがアクティブになるようにします。

仕組み

  • リクエストが開始されると、システムは現在のリクエストから JWT を抽出し、設定されたプレフィックスと現在の JWT ペイロードから抽出されたキーと値に基づいて Redis キーを組み立てます。次に、システムは ApsaraDB for Redis インスタンスでキーに対応する値を照会します。値が現在の JWT のキー値と一致しない場合、システムはアクセスリクエストを拒否します。

  • 値が存在しない場合、現在の JWT は Redis キーに書き込まれます。ApsaraDB for Redis インスタンスのキーのデフォルトの有効期限は、JWT ペイロードの exp フィールドに基づいて計算されます。つまり、キーは JWT が期限切れになるまで保存できます。JWT の有効期間中、同じペイロード特性を持つ他の JWT に基づくアクセスリクエストは許可されません。

  • リクエストのサフィックスがプラグイン設定の path と一致する場合、強制ログインメカニズムがトリガーされます。現在の JWT が関連する Redis キーの値として書き込まれると、同じペイロード特性を持つ以前に認証された JWT は無効化されます。これにより、単一デバイスログインが保証されます。

説明
  • プラグインのデフォルトで推奨されるログインキーは ["iss", "aud", "sub"] です。このキーでは、iss は JWT の発行者、aud は JWT のオーディエンス、sub は JWT のサブジェクトを示します。ほとんどの場合、この組み合わせを使用して単一デバイスログインを保証できます。

  • ApsaraDB for Redis インスタンスに保存されるキーの連結ルール: <key_prefix><PayloadKey>##<PayloadValue>。PayloadKey はシャープ記号 (#) で区切られたキーのリストです。PayloadValue はシャープ記号 (#) で区切られたキー値のリストです。例: higress_jwt_login_iss#aud#sub##xxxxx#abcde#fffff。

  • 同じペイロード特性を持つ JWT の場合、リクエストに使用された最初の JWT が自動的に ApsaraDB for Redis インスタンスに書き込まれます。これにより、プラグインの単一デバイスログイン機能が実装されます。したがって、強制ログインのために API 操作を呼び出す必要はありません。ログインシナリオで強制ログアウトが必要な場合にのみ API 操作を呼び出す必要があります。

  • ログアウトロジックをトリガーすると、ApsaraDB for Redis インスタンスに保存されている現在の JWT のログインキーがクリアされます。このルールは、JWT ログアウト機能を有効にした場合にも適用されます。

例

プラグイン設定:

redis:
  service: redis.dns
  port: 6379
jwks: |
  {
    "keys": [
      {
        "kty": "oct",
        "kid": "123",
        "k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
        "alg": "HS256"
      }
    ]
  }
login:
  path: "/jwt_login"
  key: ["iss","aud","sub"]
  error_status: 403
  error_body: |
    {"message":"already login on other device"}
  1. 正常なログイン操作を実行します。

    curl  http://xxx.hello.com/test/abc -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJ6enp6IiwiaXNzIjoiYWJjZCIsImF1ZCI6Ind3dy5leGFtcGxlLmNvbSIsInN1YiI6InRlc3QiLCJpYXQiOjE2NjU2NjA1MjcsImV4cCI6MTg2NTY3MzgxOX0.WljMr5ucxfLF8SmeaaL25c0QG3IX04HoD0als9gglYg'

    トークンペイロード:

    {
        "jti": "zzzz",
        "iss": "abcd",
        "aud": "www.example.com",
        "sub": "test",
        "iat": 1665660527,
        "exp": 1865673819
    }

    この場合、キー higress_jwt_login_iss#aud#sub##abcd#www.example.com#test は ApsaraDB for Redis インスタンスに保存され、値は現在の JWT の値と同じになります。

  2. リクエストの JWT ペイロードが同じペイロード特性を持つ場合、アクセスリクエストを拒否します。

    curl  http://xxx.hello.com/test/abc -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJqdGkiOiJ5eXl5eSIsImlzcyI6ImFiY2QiLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjY1NjYwNTI5LCJleHAiOjE4NjU2NzM4MTl9.6vi6eKPWSKHQxfzBPrj3-SWI4Q5zGtWhqp38JIN3FEo'
    
    # 次の結果が返されます:
    {"message":"already login on other device"}

    トークンペイロード:

    {
        "jti": "yyyyy",
        "iss": "abcd",
        "aud": "www.example.com",
        "sub": "test",
        "iat": 1665660527,
        "exp": 1865673819
    }

    現在の JWT とステップ 1 の JWT はペイロード特性が同じです。ただし、非特性フィールドの jti が 2 つの JWT で異なるため、この JWT に基づくアクセスリクエストは拒否されます。

  3. 強制ログインを実行します。

    curl  http://xxx.hello.com/test/jwt_login -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJqdGkiOiJ5eXl5eSIsImlzcyI6ImFiY2QiLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjY1NjYwNTI5LCJleHAiOjE4NjU2NzM4MTl9.6vi6eKPWSKHQxfzBPrj3-SWI4Q5zGtWhqp38JIN3FEo'
    
    # 次の結果が返されます:
    {"message":"login success"}

    この場合、キー higress_jwt_login_iss#aud#sub##abcd#www.example.com#test は ApsaraDB for Redis インスタンスに保存され、値は現在の JWT の値に置き換えられます。

    現在の JWT を使用してページに正常にアクセスします。

    curl  http://xxx.hello.com/test/abc -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJqdGkiOiJ5eXl5eSIsImlzcyI6ImFiY2QiLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjY1NjYwNTI5LCJleHAiOjE4NjU2NzM4MTl9.6vi6eKPWSKHQxfzBPrj3-SWI4Q5zGtWhqp38JIN3FEo'

    ステップ 1 の JWT を使用すると、失敗メッセージが返されます。

    curl  http://xxx.hello.com/test/abc -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJqdGkiOiJ4eHh4IiwiaXNzIjoiYWJjZCIsImF1ZCI6Ind3dy5leGFtcGxlLmNvbSIsInN1YiI6InRlc3QiLCJpYXQiOjE2NjU2NjA1MjcsImV4cCI6MTg2NTY3MzgxOX0.P0WtBTHJzUJvklu9q8XSRszfPbgojrZHg7t4ZaYfKGo'
    
    # 次の結果が返されます:
    {"message":"already login on other device"}

エラーコード

HTTP ステータスコード

エラーメッセージ

理由

401

invalid token

リクエストヘッダーに JWT が提供されていない、JWT 形式が無効、または JWT が期限切れか無効化されています。

500

redis server error

ApsaraDB for Redis インスタンスに到達できないか、接続がタイムアウトしました。