非対称キー暗号化を使用し、共有シークレットを使用せずに、Zonos でバックエンド サービスを認証します。
Zonos は、OAuth 2.0 JWT Bearer Token Grant (RFC 7523) を介したマシン間認証をサポートします。サービスは、RSA 秘密キーを使用して有効期間の短い JWT に署名します。 Zonos は、登録された公開キーを使用してそれを検証し、組織をスコープとするベアラー トークンを返します。
フローの概要:
Authorization: Bearer <token>
4096 ビット RSA キー ペアを生成し、公開キーを Zonos と共有します。これはオンボーディング中に 1 回実行されます。
# Generate private key
openssl genrsa -out private_key.pem 4096
# Extract public key
openssl rsa -in private_key.pem -pubout -out public_key.pem
public_key.pem を Zonos と共有します。 private_key.pem は専用のシークレット マネージャー (AWS Secrets Manager、HashiCorp Vault など) に保存します。ソース管理や環境変数には決して保存しないでください。
public_key.pem
private_key.pem
Zonos はキーを登録し、組織 ID を返します。これは、すべての JWT アサーションの iss クレームになります。
iss
秘密キーを使用して RS256 で JWT に署名します。アサーションは 1 回のトークン交換に対して有効です。有効期限を短く (60 ~ 300 秒) してください。
RS256
"org_abc123"
sub
"checkout-service"
aud
"zonos-auth"
exp
iat
jti
JWT ヘッダーでは "alg": "RS256" および "typ": "JWT" を指定する必要があります。
"alg": "RS256"
"typ": "JWT"
import jwt, uuid, time
with open("private_key.pem") as f:
private_key = f.read()
now = int(time.time())
assertion = jwt.encode(
{
"iss": "org_abc123",
"sub": "checkout-service",
"aud": "zonos-auth",
"iat": now,
"exp": now + 300,
"jti": str(uuid.uuid4()),
},
private_key,
algorithm="RS256",
)
署名された JWT を Zonos トークン エンドポイントに送信して、有効期間の短いベアラー トークンを受け取ります。
POST https://auth.zonos.com/oauth/token Content-Type: application/json
application/x-www-form-urlencodedも受け付けます。
application/x-www-form-urlencoded
grant_type
"urn:ietf:params:oauth:grant-type:jwt-bearer"
assertion
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
access_token
token_type
"Bearer"
expires_in
scope
import requests
response = requests.post(
"https://auth.zonos.com/oauth/token",
json={
: ,
: assertion,
data = response.json()
access_token = data[]
expires_in = data[]
すべての Zonos API リクエストの Authorization ヘッダーに、アクセス トークンを Bearer トークンとして含めます。
Authorization
Bearer
curl -X POST https://api.zonos.com/graphql \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{ "query": "{ ... }" }'
アクセス トークンは、デフォルトでは 5 分で期限切れになります。トークンをキャッシュし、プロアクティブに更新します。API 呼び出しごとに新しいトークンを要求しないでください。各更新には、新しく署名された JWT アサーションが必要です。
import time, requests
_cache = {"access_token": None, "expires_at": 0}
def get_access_token():
if time.time() < _cache["expires_at"] - 30:
return _cache["access_token"]
assertion = build_jwt_assertion()
data = requests.post(
"assertion": assertion,
).json()
_cache["access_token"] = data["access_token"]
_cache["expires_at"] = time.time() + data["expires_in"]
すべてのエラーは、OAuth 2.0 エラー応答形式 (RFC 6749 §5.2) に従います。
"error": "invalid_grant",
"error_description": "JWT assertion has expired"
error
400
unsupported_grant_type
urn:ietf:params:oauth:grant-type:jwt-bearer
invalid_request
401
invalid_grant
500
server_error
一般的な invalid_grant の原因:
OAuth 2.0認証
OAuth 2.0認証
非対称キー暗号化を使用し、共有シークレットを使用せずに、Zonos でバックエンド サービスを認証します。
Zonos は、OAuth 2.0 JWT Bearer Token Grant (RFC 7523) を介したマシン間認証をサポートします。サービスは、RSA 秘密キーを使用して有効期間の短い JWT に署名します。 Zonos は、登録された公開キーを使用してそれを検証し、組織をスコープとするベアラー トークンを返します。
フローの概要:
Authorization: Bearer <token>として含めます。ステップ 1 — 公開キーを登録する (1 回限りのセットアップ)
4096 ビット RSA キー ペアを生成し、公開キーを Zonos と共有します。これはオンボーディング中に 1 回実行されます。
キーペアを生成する
# Generate private keyopenssl genrsa -out private_key.pem 4096# Extract public keyopenssl rsa -in private_key.pem -pubout -out public_key.pempublic_key.pemを Zonos と共有します。private_key.pemは専用のシークレット マネージャー (AWS Secrets Manager、HashiCorp Vault など) に保存します。ソース管理や環境変数には決して保存しないでください。Zonos はキーを登録し、組織 ID を返します。これは、すべての JWT アサーションの
issクレームになります。ステップ 2 — JWT アサーションを構築する
秘密キーを使用して
RS256で JWT に署名します。アサーションは 1 回のトークン交換に対して有効です。有効期限を短く (60 ~ 300 秒) してください。必須のクレーム
iss"org_abc123")sub"checkout-service")aud"zonos-auth"である必要がありますexpiatから 60 ~ 300 秒iatjtiJWT ヘッダーでは
"alg": "RS256"および"typ": "JWT"を指定する必要があります。コード例
import jwt, uuid, timewith open("private_key.pem") as f:private_key = f.read()now = int(time.time())assertion = jwt.encode({"iss": "org_abc123","sub": "checkout-service","aud": "zonos-auth","iat": now,"exp": now + 300,"jti": str(uuid.uuid4()),},private_key,algorithm="RS256",)ステップ 3 — アサーションをアクセス トークンと交換する
署名された JWT を Zonos トークン エンドポイントに送信して、有効期間の短いベアラー トークンを受け取ります。
エンドポイント
application/x-www-form-urlencodedも受け付けます。リクエストフィールド
grant_type"urn:ietf:params:oauth:grant-type:jwt-bearer"assertionリクエストとレスポンス
{"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer","assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}access_tokentoken_type"Bearer"expires_inscope完全なコード例
import requestsresponse = requests.post("https://auth.zonos.com/oauth/token",json={: ,: assertion,},)data = response.json()access_token = data[]expires_in = data[]ステップ 4 — アクセス トークンを使用して Zonos APIs を呼び出します
すべての Zonos API リクエストの
Authorizationヘッダーに、アクセス トークンをBearerトークンとして含めます。リクエストの例
curl -X POST https://api.zonos.com/graphql \-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \-H "Content-Type: application/json" \-d '{ "query": "{ ... }" }'トークンのライフサイクルとキャッシュ
アクセス トークンは、デフォルトでは 5 分で期限切れになります。トークンをキャッシュし、プロアクティブに更新します。API 呼び出しごとに新しいトークンを要求しないでください。各更新には、新しく署名された JWT アサーションが必要です。
import time, requests_cache = {"access_token": None, "expires_at": 0}def get_access_token():if time.time() < _cache["expires_at"] - 30:return _cache["access_token"]assertion = build_jwt_assertion()data = requests.post("https://auth.zonos.com/oauth/token",json={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer","assertion": assertion,},).json()_cache["access_token"] = data["access_token"]_cache["expires_at"] = time.time() + data["expires_in"]return _cache["access_token"]エラー参照
すべてのエラーは、OAuth 2.0 エラー応答形式 (RFC 6749 §5.2) に従います。
{"error": "invalid_grant","error_description": "JWT assertion has expired"}error↕400unsupported_grant_typegrant_typeはurn:ietf:params:oauth:grant-type:jwt-bearerではありませんでした400invalid_request401invalid_grant500server_error一般的な
invalid_grantの原因:expは過去のものです - システム クロックが NTP 同期されていることを確認してくださいaudは正確には"zonos-auth"ではありませんissが登録された組織 ID と一致しませんセキュリティのベスト プラクティス
jtiを含めます。 アサーションごとに一意の値により、サーバー側のリプレイ検出が可能になります。access_tokenまたはassertionの値をログに記録しないでください。 両方を資格情報として扱います。このページは役に立ちましたか?