Refresh Tokenを使ったJWTトークンの再発行処理

🔲 Refresh Tokenを使ったJWTトークンの再発行処理

JWTトークンの有効時間は比較的短く設定されていますので、(10分程度)JWTトークンが失効するともう一度、最初から認証をやり直す必要があります。せっかく便利なSSOなのに認証操作を繰り返すのはとても不便です。そこで役に立つのが有効期間の延長です。Keycloakでは、access tokenとは別にrefresh tokenが用意されていますので、refresh tokenについて詳しく説明します。

Keycloakのリフレッシュトークン(refresh_token)は、認証されたユーザーセッションを維持し、セキュリティと利便性を両立するための重要な機能です。その目的と機能については以下の通りです。

Refresh tokenの目的

  1. ユーザーエクスペリエンスの向上: access tokenはセキュリティの観点から短期間で失効するため、ユーザーがログインして一定時間経過後にもシームレスにサービスを利用できるようにrefresh tokenが利用されます。これにより、ユーザーは長時間ログインし続けることができ、毎回再ログインする手間を省くことが可能です。
  2. セキュリティの強化: refresh tokenは通常、access tokenよりも長い有効期限を持ちますが、access tokenより安全性が高くなるよう設計されています。これにより、長期セッションでもセキュリティを維持しながら、access tokenを短期間で無効にすることができ、もしaccess tokenが漏洩しても影響を最小限に抑えることができます。
  3. セッション管理の効率化: Keycloakではrefresh tokenを使うことで、サーバーとクライアントの間での認証リクエストの数を減らすことができます。これにより、認証システムの負荷を軽減し、システム全体のパフォーマンス向上が期待できます。

Refresh tokenの機能

refresh tokenは、access tokenが期限切れになった場合に新しいaccess tokenを発行するための一時的なトークンです。通常、access tokenには有効期限が設定されており、一定時間経過すると期限切れとなり、再度認証が必要になります。しかし、毎回の認証ではユーザー体験が損なわれるため、refresh tokenを使用することで、再度パスワードや認証情報を要求せずにセッションを延長することが可能です。

Keycloakにおけるrefresh tokenの使用方法

Keycloakでは、refresh tokenはOAuth 2.0プロトコルに従って発行されます。ユーザーがログインすると、access tokenとともにrefresh tokenが返されます。クライアントはaccess tokenが期限切れになる前、または期限切れになった後にrefresh tokenを使って新しいaccess tokenを取得します。このプロセスは、バックエンドで非同期的に処理され、ユーザーにはその更新が見えない形で処理可能です。

refresh tokenは、Keycloakの管理コンソールで設定可能です。有効期限やトークンの更新方法をカスタマイズでき、セキュリティポリシーやユーザーエクスペリエンスに合わせて最適化することができます。refresh tokenの有効期間が過ぎると、ユーザーは再度完全な認証プロセスを経る必要があります。

🔸 refresh tokenを使ってaccess tokenを取得する

node-redのflowは下記の通りです。プログラム全体の構成は、JWTトークンの取得と同じ構成です。

異なる点は、refresh tokenを使うことです。

  • パラメータとしては、以下の通りです。
    • client_id:”test-client”
    • client_secret:secret_key   ※シークレット鍵です。
    • grant_type:”refresh_token”
    • refresh_token:refresh_token ※JWTから抜き出したrefresh tokenデータ
const host_ip = msg.host_ip;
const secret_key = msg.secret_key;
const refresh_token = msg.refresh_token;
msg.payload = { "client_id": "test-client", 
                "client_secret": secret_key,
                "grant_type":"refresh_token",
                "refresh_token": refresh_token
              };
msg.headers = {"Content-Type":"application/x-www-form-urlencoded"};
const endpoint = "/realms/demo/protocol/openid-connect/token";
msg.url = host_ip + endpoint;
return msg;

プログラムの実行結果です。再び新しくなったJWTトークンが返ってきます。取得したasscess token以外にも次に使えるrefresh tokenが含まれています。

取得したaccess tokenを検証してみましょう。

同じ結果が得られました。「payload: true」これで、ユーザからの認証を求めることなく、継続したサービスを安全に提供することができます。