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

Identity as a Service:M2M クライアントトークン呼び出しの例

最終更新日:Apr 01, 2026

Alibaba Cloud IDaaS (EIAM) におけるマシンツーマシン (M2M) 認証用のアクセストークンを取得するには、OAuth 2.0 クライアントクレデンシャルフローを使用します。このページでは、サポートされている各認証方式について、リクエストおよび応答の例を提供します。

認証方式の選択

すべての方式は同じトークンエンドポイントに POST リクエストを送信します。アプリケーションの認証情報タイプに一致する方式を選択してください。

方式認証情報タイプセキュリティレベル使用タイミング
client_secret_basic共有シークレット (HTTP Basic)標準Authorization ヘッダーでシークレットを送信するシンプルな統合
client_secret_post共有シークレット (リクエストボディ)標準カスタムヘッダーを設定できないクライアント
client_secret_jwt共有シークレット、JWT 署名 (HS256)生のシークレットを通信経路上で送信したくない場合
private_key_jwtRSA 秘密鍵、JWT 署名 (RS256)最高非対称キーによるセキュリティが求められる本番システム
OIDC フェデレーション認証外部 OIDC トークンすでに ID プロバイダー (例:Alibaba Cloud ACK) から OIDC トークンを保持しているサービス
PKCS#7 署名認証PKCS#7 署名PKCS#7 署名を生成するシステム (例:ハードウェアセキュリティモジュール)
プライベート CA 証明書認証X.509 クライアント証明書プライベート認証局を使用するインフラストラクチャ

前提条件

作業を開始する前に、以下の要件を満たしていることを確認してください。

  • M2M が設定された IDaaS EIAM インスタンス

  • アプリケーション ID (client_id) および、選択した方式に応じた認証情報 (クライアントシークレット、秘密鍵、または証明書)

  • IDaaS EIAM に少なくとも 1 つのリソースサーバーとスコープが設定済みであること

  • ご利用のインスタンスのトークンエンドポイント URL:https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token

トークンエンドポイント

すべての方式は、次のエンドポイントに POST リクエストを送信します。

POST https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token

認証方式

client_secret_basic

client_id および client_secret を Base64 文字列としてエンコードし、Authorization ヘッダーで渡します。

ヘッダーパラメーター

パラメータータイプ必須説明
AuthorizationStringはいBasic に続いて <client_id>:<client_secret>Basic YXBwX201ZG9vemVzbm81Mmtxxxxxxxxx
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|read:file
client_idStringはいアプリケーション IDapp_m5doozesno52kbqrqpw3xxxx

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Authorization: Basic <base64-encoded-client-id-and-secret>' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'scope=api://api.example.com|read:file'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2sep******HBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

client_secret_post

client_id および client_secret をリクエストボディに直接渡します。Authorization ヘッダーは不要です。

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション IDapp_m5doozesno52kbqrqpw3xxxx
client_secretStringはいアプリケーションシークレットCS5v3F4Cy8hyDmFPJtAuyHDTUdR8i88GcgcXXXXX
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|read:file

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'client_secret=<your-client-secret>' \
     --data-urlencode 'scope=api://api.example.com|read:file'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2******kxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

client_secret_jwt

client_secret (HS256 アルゴリズム) を使用して JWT に署名し、client_assertion として渡します。生のシークレットは通信経路上で送信されません。

完全なコード例については、「付録 2:Java を使用した JWT 署名の生成 (HS256)」をご参照ください。

client_assertion に必要な JWT クレーム

クレーム説明
iss発行者ご利用の client_id
subサブジェクトご利用の client_id
audオーディエンストークンエンドポイント URL
exp有効期限発行時刻から 30 分以内である必要があります
jtiJWT IDリプレイ防止のため、リクエストごとに一意の UUID

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション ID
client_assertion_typeStringはい常に urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertionStringはいHS256 を使用して client_secret で署名された JWT
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|read:file

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
     --data-urlencode 'client_assertion=<your-jwt-token>' \
     --data-urlencode 'scope=api://api.example.com|read:file'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2se******NHBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

private_key_jwt

RSA 秘密鍵 (RS256 アルゴリズム) を使用して JWT に署名し、client_assertion として渡します。これは本番システム向けの最も安全なオプションです。

完全なコード例については、「付録 1:Java を使用した JWT 署名の生成 (RS256)」をご参照ください。

client_assertion に必要な JWT クレーム

クレーム説明
iss発行者ご利用の client_id
subサブジェクトご利用の client_id
audオーディエンストークンエンドポイント URL
exp有効期限発行時刻から 30 分以内である必要があります
jtiJWT IDリプレイ防止のため、リクエストごとに一意の UUID

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション ID
client_assertion_typeStringはい常に urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertionStringはいRS256 を使用して RSA 秘密鍵で署名された JWT
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|read:file

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
     --data-urlencode 'client_assertion=<your-jwt-token>' \
     --data-urlencode 'scope=api://api.example.com|read:file'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2sep******NHBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

OIDC フェデレーション認証

外部 ID プロバイダー (例:Alibaba Cloud ACK) によって発行された既存の OIDC トークンを client_assertion として使用します。アプリケーションには、IDaaS EIAM に一致するフェデレーション認証情報が設定されている必要があります。

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション ID
client_assertion_typeStringはい常に urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer
client_assertionStringはいJWT 形式の OIDC トークン
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|.all
application_federated_credential_nameStringはいアプリケーションのフェデレーション認証情報の名前aliyun_ack

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'scope=api://api.example.com|.all' \
     --data-urlencode 'application_federated_credential_name=<federated-credential-name>' \
     --data-urlencode 'client_assertion=<your-oidc-token>' \
     --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:id-token-bearer'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2sep******7NHBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

PKCS#7 署名認証

PKCS#7 署名を client_assertion として使用します。アプリケーションには、IDaaS EIAM に一致するフェデレーション認証情報が設定されている必要があります。

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション ID
client_assertion_typeStringはい常に urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer
client_assertionStringはいPKCS#7 署名の値
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|.all
application_federated_credential_nameStringはいアプリケーションのフェデレーション認証情報の名前aliyun_ecs

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'scope=api://api.example.com|.all' \
     --data-urlencode 'application_federated_credential_name=<federated-credential-name>' \
     --data-urlencode 'client_assertion=<your-pkcs7-signature>' \
     --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:pkcs7-bearer'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2sep******7NHBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

プライベート CA 証明書認証

プライベート CA によって発行された JWT および X.509 証明書チェーンを提示します。アプリケーションには、IDaaS EIAM に一致するフェデレーション認証情報が設定されている必要があります。

ヘッダーパラメーター

パラメータータイプ必須説明
Content-TypeStringはい常に application/x-www-form-urlencodedapplication/x-www-form-urlencoded

リクエストパラメーター

パラメータータイプ必須説明
grant_typeStringはい常に client_credentialsclient_credentials
client_idStringはいアプリケーション ID
client_assertion_typeStringはい常に urn:cloud:idaas:params:oauth:client-assertion-type:x509-jwt-bearer
client_assertionStringはいクライアントが秘密鍵を使用して発行した JWT
scopeStringはいスペース区切りのスコープリスト。各スコープは <resourceServerIdentifier>|<scope> 形式を使用します。<resourceServerIdentifier>|.all を使用すると、承認済みのすべてのスコープを要求できます。api://api.example.com|.all
client_x509StringはいDER 形式で Base64 エンコードされたエンドエンティティ証明書 (リーフ証明書)-----BEGIN CERTIFICATE-----xxxxxx-----END CERTIFICATE-----
client_x509_chainStringはいDER 形式で Base64 エンコードされた中間 CA 証明書を改行で連結したもの。各証明書は次の形式に従う必要があります:-----BEGIN CERTIFICATE-----<certificate-content>-----END CERTIFICATE-----
application_federated_credential_nameStringはいアプリケーションのフェデレーション認証情報の名前private_ca

リクエスト例

curl --request POST \
     --url 'https://<instance-id>.aliyunidaas.com/api/v2/iauths_system/oauth2/token' \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode 'client_id=<your-client-id>' \
     --data-urlencode 'grant_type=client_credentials' \
     --data-urlencode 'scope=api://api.example.com|.all' \
     --data-urlencode 'application_federated_credential_name=<federated-credential-name>' \
     --data-urlencode 'client_assertion=<your-jwt-token>' \
     --data-urlencode 'client_assertion_type=urn:cloud:idaas:params:oauth:client-assertion-type:x509-jwt-bearer'

応答パラメーター

パラメータータイプNull 許容説明
access_tokenStringいいえアクセストークンの値
expires_inLongいいえトークンの有効期間 (秒)
expires_atLongいいえUNIX タイムスタンプ (秒) でのトークンの有効期限
token_typeStringいいえ常に Bearer

応答例

{
  "token_type": "Bearer",
  "access_token": "AT8csE2sepE******7NHBkxxHUG",
  "expires_in": 3600,
  "expires_at": 1733710213
}

エラーコード

HTTP コードエラーエラーメッセージ説明
400invalid_request必須パラメーター変数:grant_type必須パラメーターが不足している、無効な値がある、複数回出現している、またはリクエストが不正な形式です。
400authentication_required認証が必要です。許可された認証方式:[client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt]認証方式がサポートされていません。サポートされている方式:client_secret_basicclient_secret_postclient_secret_jwtprivate_key_jwt
400invalid_client_credential無効な client_assertion。理由:[expired]client_assertion が無効です。トークンの有効期限が切れています。
400invalid_grant無効またはサポートされていない grant_type:authorization_codegrant_type の値がサポートされていません。
400invalid_scope無効なスコープ:http://www.example.com|read:file要求されたスコープが無効、不明、または形式が正しくありません。
500internal_error予期しない内部エラー内部サーバーエラーが発生しました。

付録 1:Java を使用した JWT 署名の生成 (RS256 アルゴリズム)

この例を使用して、private_key_jwt 認証方式用の client_assertion JWT を生成します。JWT は RS256 アルゴリズムを使用して RSA 秘密鍵で署名されます。

Maven 依存関係

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

Java コード例

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtGenerator {
    private static final String PRIVATE_KEY = "your-private-key"; // ご利用の秘密鍵に置き換えてください

    // ご利用のアプリケーションの client_id を入力してください
    private static final String ISSUER = "your_client_id";

    // ご利用のアプリケーションの client_id を入力してください
    private static final String SUBJECT = "your_client_id";

    // ご利用のアプリケーションのトークンエンドポイントを入力してください
    private static final String AUDIENCE = "your_token_endpoint";

    public static void main(String[] args) throws Exception {
        // 鍵
        Key securityKey = RsaKeyConverter.getPrivateKeyFromString(PRIVATE_KEY);

        Map<String, Object> claims = new HashMap<>();
        claims.put("jti", UUID.randomUUID().toString()); // リプレイ防止の jti

        // 有効期限を設定します。30 分を超えてはいけません。
        long expirationTime = 1000 * 60 * 30;
        Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);

        // JWT を生成します
        String jwt = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(expirationDate)
                .setSubject(SUBJECT)
                .setIssuer(ISSUER)
                .setAudience(AUDIENCE)
                .signWith(securityKey, SignatureAlgorithm.RS256)
                .compact();

        System.out.println("Generated JWT:");
        System.out.println(jwt);
    }
}

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RsaKeyConverter {

    public static PrivateKey getPrivateKeyFromString(String privateKeyStr) throws Exception {
        // PEM 形式のヘッダーとフッターを削除します
        String privateKeyPEM = privateKeyStr
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");  // すべての空白文字を削除します

        // Base64 デコード
        byte[] encoded = Base64.getDecoder().decode(privateKeyPEM);

        // PKCS8EncodedKeySpec を使用して秘密鍵を生成します
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    public static PublicKey getPublicKeyFromString(String publicKeyStr) throws Exception {
        // PEM 形式のヘッダーとフッターを削除します
        String publicKeyPEM = publicKeyStr
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s+", "");  // すべての空白文字を削除します

        // Base64 デコード
        byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);

        // X509EncodedKeySpec を使用して公開鍵を生成します
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }
}

付録 2:Java を使用した JWT 署名の生成 (HS256 アルゴリズム)

この例を使用して、client_secret_jwt 認証方式用の client_assertion JWT を生成します。JWT は HS256 アルゴリズムを使用して client_secret で署名されます。

Maven 依存関係

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-api</artifactId>
  <version>0.11.5</version>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-impl</artifactId>
  <version>0.11.5</version>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-jackson</artifactId>
  <version>0.11.5</version>
  <scope>runtime</scope>
</dependency>

Java コード例

public class JwtGenerator {

    private static final String SECRET_KEY = "your_secret_key"; // ご利用のシークレットキーに置き換えてください

    // ご利用のアプリケーションの client_id を入力してください
    private static final String ISSUER = "your_client_id";

    // ご利用のアプリケーションの client_id を入力してください
    private static final String SUBJECT = "your_client_id";

    // ご利用のアプリケーションのトークンエンドポイントを入力してください
    private static final String AUDIENCE = "your_token_endpoint";

    public static String generateJwt() throws Exception {
        SecretKey secretKey = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());

        Map<String, Object> claims = new HashMap<>();
        claims.put("jti", UUID.randomUUID().toString()); // リプレイ防止の jti

        // 有効期限を設定します。30 分を超えてはいけません。
        long expirationTime = 1000 * 60 * 30;
        Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);

        // JWT を生成します
        String jwt = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(expirationDate)
                .setSubject(SUBJECT)
                .setIssuer(ISSUER)
                .setAudience(AUDIENCE)
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .compact();
        return jwt;
    }

    public static void main(String[] args) throws Exception{
        // JWT を生成します
        String jwt = generateJwt();
        System.out.println("Generated JWT: " + jwt);
    }
}