認証
すべての IDCloud API(Web & SDK および API コントラクト)は、OAuth2 JWT Bearer Grant Type(RFC 7523)を使用します。バックエンドで短命の JWT アサーションを生成し、それを Bearer トークンと交換して、以降のすべての呼び出しでそのトークンを使用します。
JWT アサーションはバックエンドのみで生成する必要があります。フロントエンドコード、モバイルアプリ、リポジトリ、またはログに秘密鍵を公開しないでください。
認証情報の取得
トークンを生成する前に、Unico によってプロビジョニングされたサービスアカウントが必要です。Unico サポートに連絡し、以下の情報を提供してください:
- サービスアカウント名(最大 12 文字)
- 担当者の氏名、メールアドレス、電話番号(ブラジル、米国、またはメキシコの番号のみ)
以下の情報が提供されます:
- 一意のアカウント名
- テナント ID
- 基本 JWT ペイロード
- 秘密鍵ファイル(
.pem形式)
UAT と本番環境のサービスアカウントは別々に管理してください。
JWT アサーションの構築
アサーションは JWS コンパクト形式の JWT です:{Base64url(Header)}.{Base64url(Payload)}.{Base64url(Signature)}。
{
"alg": "RS256",
"typ": "JWT"
}
| クレーム | 値 | 備考 |
|---|---|---|
iss | <account_name>@<tenant_id>.iam.acesso.io | 認証情報と一緒に提供されます |
aud | https://identityhomolog.acesso.io(UAT)または https://identity.acesso.io(本番) | トークンエンドポイントのホストと一致する必要があります |
scope | * | すべての権限を付与します |
iat | Unix タイムスタンプ(秒) | JWT が発行された時刻 |
exp | iat + 最大 3600 | iat から 1 時間を超えることはできません |
{
"aud": "https://identity.acesso.io",
"scope": "*",
"iat": 1738086000,
"exp": 1738089600
}
Unico から提供された .pem 秘密鍵を使用して、RS256(RSA + SHA-256)でヘッダーとペイロードに署名します。
上記以外のフィールド(例:sub、jti、nbf)は 1.2.22 エラーを引き起こします。示されているクレームのみを使用してください。
トークンのリクエスト
トークンエンドポイントは両方のコントラクトで同一です:
| 環境 | エンドポイント |
|---|---|
| 本番 | POST https://identity.acesso.io/oauth2/token |
| UAT | POST https://identityhomolog.acesso.io/oauth2/token |
| パラメーター | 値 |
|---|---|
Content-Type | application/x-www-form-urlencoded |
grant_type | urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion | 署名済み JWT |
- cURL
- Node.js
- Python
curl -X POST https://identity.acesso.io/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
import jwt from 'jsonwebtoken';
import fs from 'fs';
import qs from 'querystring';
const privateKey = fs.readFileSync('./private-key.pem');
const now = Math.floor(Date.now() / 1000);
const assertion = jwt.sign(
{
aud: 'https://identity.acesso.io',
scope: '*',
iat: now,
exp: now + 3600,
},
privateKey,
{ algorithm: 'RS256' }
);
const res = await fetch('https://identity.acesso.io/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: qs.stringify({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion,
}),
});
const { access_token, expires_in } = await res.json();
import time
import jwt # PyJWT
import requests
with open("private-key.pem", "rb") as f:
private_key = f.read()
now = int(time.time())
assertion = jwt.encode(
{
"aud": "https://identity.acesso.io",
"scope": "*",
"iat": now,
"exp": now + 3600,
},
private_key,
algorithm="RS256",
)
response = requests.post(
"https://identity.acesso.io/oauth2/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": assertion,
},
)
token_data = response.json()
access_token = token_data["access_token"]
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
| フィールド | 型 | 説明 |
|---|---|---|
access_token | string | JWT アクセストークン。すべての API 呼び出しで Authorization: Bearer <token> として使用します。 |
expires_in | integer | 有効期限(秒単位)。例:3600。 |
token_type | string | 常に Bearer。 |
トークンの使用
すべての API リクエストの Authorization ヘッダーにトークンを追加します。ヘッダーは両方のコントラクトで同一で す — 異なるのは呼び出す API のホストとパスです:
| コントラクト | 本番ホスト | UAT ホスト |
|---|---|---|
| Web & SDK | https://api.idcloud.unico.app | https://api.idcloud.uat.unico.app |
| API | https://api.id.unico.app | https://api.id.uat.unico.app |
Web & SDK — Authorization は唯一必要な認証ヘッダーです:
curl -X POST https://api.idcloud.unico.app/client/v1/process \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }'
API — Authorization は APIKEY ヘッダーと合わせて使用します:
curl -X POST https://api.id.unico.app/processes/v1 \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "APIKEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'
トークンの更新
トークンは 3600 秒後に失効します。バックエンドでプロアクティブな更新を実装してください:
- トークンレスポンスから
expires_inを追跡し、有効期限のタイムスタンプを保存します。 - 有効期限の10 分前以内に新しいトークンをリクエストします。
- 本番環境で更新をトリガーするために
401を待たないでください。
API リファレンス
トークンエンドポイントの完全な OpenAPI 仕様は authentication.yaml で参照できます。
| メソッド | パス | 説明 |
|---|---|---|
POST | /oauth2/token | 署名済み JWT アサーションを Bearer アクセストークンと交換する |
エラーコード
| コード | 説明 | 対処法 |
|---|---|---|
1.0.1 | iss の形成に使用された ID が正しくありません | iss フィールドが秘密鍵生成時に提供されたテナント ID と一致しているか確認してください |
1.0.14 | アプリケーションがアクティブではありません | 使用しているアプリケーションがアクティブかどうかプロジェクトマネージャーに確認してください |
1.1.1 | scope パラメーターが提供されていません | JWT ペイロードに "scope": "*" を追加してください |
1.2.4 | JWT アサーションが無効です | JWT アサーションが有効ではなくなっています。原因は2つあります: (a) 現在時刻が exp を過ぎている(JWT が本当に失効 — 各トークンリクエストのために新しいアサーションを生成してください); または (b) exp が iat + 3600 を超えている(有効期間が長すぎる — exp を iat + 3600 に制限してください)。 |
1.2.5 | JWT 検証に失敗しました | JWT を検証できません。パラメーターを確認し、RS256 と正しい秘密鍵で署名されていることを確認してくだ さい |
1.2.6 | 秘密鍵が無効になっています | JWT の署名に使用した秘密鍵が受け入れられなくなりました。アカウントの新しい認証情報をリクエストしてください |
1.2.7 | JWT はすでに使用されています | JWT はすでに使用されているため、受け入れられなくなりました。各トークンリクエストに新しいアサーションを生成してください |
1.2.11 | アカウントがアクティブではありません | 使用しているアカウントがアクティブではありません |
1.2.14 | アカウントに必要な権限がありません | 使用しているアカウントには必要な権限がありません |
1.2.18 | アカウントが一時的にロックされています | 無効な認証試行回数を超えたため、アカウントが一時的にロックされています |
1.2.19 | 許可されていないユーザーなりすまし | JWT に、なりすましが許可されていないアカウントを指す sub クレームが含まれています。ペイロードから sub クレームを削除してください。 |
1.2.20 | JWT デコードに失敗しました | JWT のデコードに失敗しました。トークン形式と RS256 で署名されていることを確認してください。 |
1.2.21 | 誤った秘密鍵 / 認証失敗 | このアカウントの既知のキーに対して JWT 署名を検証できませんでした。このサービスアカウントと環境に正しい .pem 秘密鍵を使用していることを確認してください。 |
1.2.22 | ペイロードに許可されていないフィールドがあります | JWT に許可されていない追加ペイロードフィールドが含まれています。このガイドに記載されていないクレーム(例:sub、jti、nbf)を削除してください。注: sub クレームを含めて 1.2.19 を受け取った場合、そのエラーが優先されます。 |
1.3.1 | IP アクセス制限 | お使いの IP はこのアカウントの許可リストにありません |
1.3.2 | 時間ベースのアクセス制限 | リクエストがこのアカウントの許可された時間枠外です |
次のステップ
- 環境 — サンドボックスと本番ホスト
- Web & SDK — プロセス作成 — 認証後の最初の呼び出し
- API — プロセス作成 — 認証後の最初の呼び出し
- SSO / SAML — 上記のサーバー間フローの代わりに、自社のIDプロバイダーを使用してUnicoの各製品ポータルにユーザーを認証させる方法