このドキュメントは 開発者が AWS Cognito(以下 Cognito)を利用して、KMIoT-API を利用するための手順を記載します。KMIoT-API のエンドポイントの詳細は Swagger ドキュメントをご参照ください。
対象: KMIoT が提供する BFF(Backend for Frontend) を利用して SPA/フロントから KMIoT-API を呼びたい開発者/範囲: M2M / LLM 連携は扱いません。PKCE + BFF 前提で、フロント実装に必要な最小事項を説明します。
本サービスでは以下のようなシーケンスにて動作します。
契約・テナントごとにサポートから以下が案内されます。
https://<bff>.kmiot-app.net — フロントは常に本 BFF を呼びます(/api/kmiot/**)。https://<tenant>.auth.ap-northeast-1.amazoncognito.com。openid profile email myapi/api.read(参照系)。更新系が必要なら myapi/api.write も。https://app.example.com)。Cookie 同送のため CORS + credentials 設定が必須。/auth/logout など)。標準ではユーザのフロントから直接 KMIoT-API へのアクセス不可となりますので、別途 KMIoT-API のカスタマイズが必要です。
(※本アクセスが必要な環境をご利用になる場合はサポートへご連絡ください。)
重要: フロントは トークンを保持しません。BFF がサーバ側セッションで管理します。
GET /auth/client-config)SPA はまず /auth/client-config を呼び、ログインパラメータ名やCSRF 設定、リフレッシュ/ログアウトのエンドポイント等を動的に取得できます。
// 例: 起動時に一度だけ読み込む
const conf = await fetch('https://<bff>.kmiot-app.net/auth/client-config', { credentials: 'include' }).then(r => r.json());
// conf 例:
// {
// "loginParam": "next",
// "aliases": ["returnTo"],
// "nextRules": "relative-only",
// "csrfHeader": "X-CSRF-Token",
// "csrfEndpoint": "/csrf",
// "refreshEndpoint": "/auth/refresh",
// "logoutEndpoint": "/auth/logout",
// "issuer": "https://tenant.auth.ap-northeast-1.amazoncognito.com",
// "apiPrefix": "/api/kmiot",
// "version": "v1"
// }
規約: ログイン遷移クエリは next(互換: returnTo)で、相対パスのみ許可します(http(s):// や // は不可)。
<a href="https://<bff>.kmiot-app.net/auth/login?next=%2Fapp%2Fhome">ログイン</a>
Hosted UI でサインイン後、BFF の /auth/callback を経由して next に自動遷移します(ポップアップの場合は自動クローズ)。
// 参照系(例: センサー一覧)
const res = await fetch('https://<bff>.kmiot-app.net/api/kmiot/v2/sensorinfo/th', {
method: 'GET',
credentials: 'include', // ← 重要(sid Cookie を送る)
});
if (res.status === 401) {
location.href = 'https://<bff>.kmiot-app.net/auth/login?next=' + encodeURIComponent(location.pathname);
}
const data = await res.json();
// 参照系(例: グラフデータ)
const res2 = await fetch('https://<bff>.kmiot-app.net/api/kmiot/v2/graphdata', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
kind: 'th',
from: '2025-09-20T00:00:00Z',
to: '2025-09-21T00:00:00Z',
}),
});
const data2 = await res2.json();
// 1) まず CSRF トークンを取得(Cookie + JSON)
const t = await fetch('https://<bff>.kmiot-app.net/csrf', { credentials: 'include' }).then(r => r.json());
// 2) 書き込み時にヘッダへ付与
await fetch('https://<bff>.kmiot-app.net/api/kmiot/v2/alertsetting', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': t.csrfToken },
body: JSON.stringify({ sensorkind: 'door', limit_open: '120', limit_close: '0' }),
});
async function fetchWithRefresh(input, init = {}) {
const res = await fetch(input, { ...init, credentials: 'include' });
if (res.status !== 401) return res;
const r = await fetch('https://<bff>.kmiot-app.net/auth/refresh', { method: 'POST', credentials: 'include' });
if (r.ok) return fetch(input, { ...init, credentials: 'include' });
location.href = 'https://<bff>.kmiot-app.net/auth/login?next=' + encodeURIComponent(location.pathname + location.search + location.hash);
}
GET /auth/client-config(JSON: loginParam, aliases, nextRules, csrfHeader, csrfEndpoint, refreshEndpoint, logoutEndpoint ほか)GET /csrf → { csrfToken } + Cookie(SameSite=Lax/None)GET /auth/login?next=<相対パス>(互換: returnTo)GET /auth/callback(トークン交換→Cookie 設定→自動遷移)POST /auth/refresh(Cookie の RT で AT 更新)POST /auth/logout(セッション破棄+Cognito ログアウトへ誘導可)GET /api/kmiot/v2/sensorinfo/{kind}、POST /api/kmiot/v2/graphdata、POST /api/kmiot/v2/alertsetting、GET /api/kmiot/v2/imagedata など。| HTTP | JSON 例 | 対処 |
|---|---|---|
| 401 | {"error":"no_session"} / {"error":"invalid_token","detail":"jwt expired"} | まず /auth/refresh → 単回リトライ。ダメなら /auth/login |
| 403 | {"error":"csrf_required"} | /csrf を取得し直して再送 |
| 403 | {"error":"insufficient_scope"} | スコープ不足。サポートへ連絡 |
| 404 | {"error":"sensor_not_found"} | パラメータ(kind 等)確認 |
| 5xx | {"error":"..._failed"} | リトライ。継続時はサポートへ連絡 |
fetch は credentials: "include" を付与。https://app.example.com 等)は サポートへ申請し CORS 許可。/auth/logout を利用。/oauth2/token をフロントから直接叩きますか?KMIoT 提供BFFを通じて KMIoT-API を利用する際の必須ルールです。
401 を返し、再ログインが必要です。/csrf → X-CSRF-Token)。/auth/client-config の csrfHeader / csrfEndpoint により仕様が自己記述されます。GET /auth/refresh の存在とレスポンス例を公開します。401 発生時の再ログイン vs 自動リフレッシュの切り替えルールを明示します。error_code, error)の意味を定義します。credentials:"include" で Cookie を送信してください。next(エイリアス returnTo)に相対パスのみ許可します。技術サポート/許可オリジン登録・スコープ追加の依頼は、契約書記載の サポート窓口 へご連絡ください。
本付録は PKCE + BFF の一般パターンを前提に、KMIoT 固有の前提(Issuer/スコープ/パス等)を明示します。公式運用は「KMIoT 提供 BFF の利用」を推奨します。
myapi/api.read、更新 myapi/api.write。/v2/*(例:/v2/sensorinfo/th、/v2/graphdata、/v2/imagedata、/v2/alertsetting)。from < to。{
"apiBase": "https://api.kmiot-app.net",
"version": "v2",
"authDomain": "https://<tenant>.auth.ap-northeast-1.amazoncognito.com",
"clientId": "<PUBLIC_CLIENT_ID>",
"scopes": ["openid","profile","email","myapi/api.read"],
"token": { "accessTtlSec": 3600, "refreshTtlDays": 30, "clockSkewSec": 60 },
"callbacks": {
"login": "https://bff.example.com/auth/callback",
"logout": "https://bff.example.com/auth/logout"
},
"oidcDiscovery": "https://<tenant>.auth.ap-northeast-1.amazoncognito.com/.well-known/openid-configuration",
"rateLimit": { "perMinute": 600, "burst": 200 },
"contact": { "support": "support@kmiot-app.net" }
}
/auth/login(state, code_challenge=S256)→ /auth/callback(server-side /oauth2/token)。sid のみ。
SameSite=Lax/Strict でも可。SameSite=None; Secure + CORS + credentials:"include"。Authorization: Bearer <AT> を付与して /v2/* を呼ぶ。/csrf → X-CSRF-Token)。Access-Control-Allow-Credentials: true。呼び先のベース URL だけが変わることを目標にします。
https://<bff>.kmiot-app.net/api/kmiot/... → https://<your-bff.example.com>/api/kmiot/...
どちらでも credentials:"include" は必須(Cookie 送信)。
/auth/login → 認可 → /auth/callback → sid 付与。GET /api/kmiot/v2/sensorinfo/th が 200。POST /api/kmiot/v2/alertsetting は CSRF 無しで 403、CSRF 付与で 200。X-Request-Id)でトレース可能。https://bff.example.comhttps://bff.example.com/auth/callbackhttps://bff.example.com/auth/logout(使用時)https://app.example.com(複数可)