# 身份驗證

> 了解各 Kanorio API 接受的憑證類型、權限計算方式，以及如何安全地輪替與撤銷權杖。

> Markdown version of https://kanorio.com/zh-Hant/developers/authentication. Append `.md` to any developer docs URL for this format. Index: https://kanorio.com/llms.txt · MCP: https://app.kanorio.com/api/mcp
>
> Translated from the English original: https://kanorio.com/en/developers/authentication.md

每個 Kanorio API 均針對不同的呼叫者所建構，並各自接受專屬的憑證。請透過確認呼叫者的身份來選擇對應的憑證。

| 權杖 | 前綴 | 身分 | 適用於 | 用途 |
|---|---|---|---|---|
| 個人存取權杖 | `knr_pat_` | 您本人，受限於您選擇的網站與權限 | Management API, MCP | 您的腳本、CLI、需要金鑰的程式輔助工具 |
| 服務帳戶權杖 | `knr_sa_` | 網站本身，非特定個人 | Management API, MCP | CI、排程器以及在人員離職後仍需持續運行的合作夥伴後端 |
| OAuth 存取權杖 | `knr_at_` | 您本人，透過您授權的應用程式 | 僅限 MCP | 內建連接器的輔助工具，例如 Claude 或 ChatGPT |
| 預覽權杖 | `knr_pv_` | 單一網站草稿的唯讀存取權 | Content Delivery API | 您自建前端的草稿模式 |
| 顧客權杖 | `knr_cat_` | 單一網站的單一登入顧客 | Customer API, 受限的 Content Delivery API 讀取 | 您前端的登入、購買內容與訂單 |

Content Delivery API 對於已發佈的內容無需任何憑證。

## Management API

在每次請求 `https://app.kanorio.com/api/v1` 時，請將權杖作為 Bearer 憑證發送。

```bash
curl https://app.kanorio.com/api/v1/sites \
  -H "Authorization: Bearer knr_pat_..."
```

### 個人存取權杖

請在 [帳戶設定 › API 存取](https://app.kanorio.com/account/api-access) 中建立權杖。建立時您需要選擇：

- **網站。** 指定網站，或包含您日後建立的所有網站。建立新網站需要「所有網站」權限。
- **權限。** 選擇預設集（唯讀、編輯內容、完整存取）或個別權限。
- **過期時間。** 權杖皆會過期。過期前您會收到電子郵件與收件匣通知。

權杖在網站上的有效權限，為該權杖允許的範圍與您在該網站角色權限的交集。即使是完整存取權杖，也無法編輯您僅具備檢視者角色的網站，且僅有網站擁有者可以取消發佈。

無論選擇何種預設集，某些權限永遠不會授權給權杖，包括發送或排程電子報、匯出資料、退款、刪除聯絡人，以及管理成員或帳務。代理人可以草擬電子報，但必須由人員從後台發送。

### 服務帳戶

服務帳戶屬於網站，而非個人。即使建立該帳戶的人員離開團隊，它仍能持續運作；撤銷服務帳戶將會同時撤銷其發出的所有權杖。

1. 開啟 [網站設定 › 開發者](https://app.kanorio.com/settings/developer) 並新增服務帳戶。您僅能授予您自身擁有的權限。
2. 開啟該帳戶並發出權杖。請以其用途命名權杖，例如「GitHub Actions」。`knr_sa_` 值僅會顯示一次。

服務帳戶僅能在其所屬網站內運作。帳戶層級的操作（例如建立網站或列出您所有的網站）會回傳 `403 FORBIDDEN`。在 [OpenAPI 文件](https://app.kanorio.com/api/v1/openapi.json) 中的每個操作皆列出了其接受的呼叫者類型（於 `x-kanorio-principals` 欄位）；包含 `SERVICE_ACCOUNT` 的操作才接受服務帳戶權杖。

縮減服務帳戶的權限會立即縮減其現有權杖的權限。擴大權限則僅適用於後續發出的權杖。

### 範圍

[Management API 參考](https://kanorio.com/en/developers/management-api) 中的每個操作皆顯示了其所需的權限。OpenAPI 文件中標註了相同的 `x-kanorio-required-scope` 值。若權杖缺少該範圍，將會收到 `403 FORBIDDEN`。請呼叫 `GET /whoami` 以查看目前權杖的權限。

## MCP

MCP 伺服器位於 `https://app.kanorio.com/api/mcp`，它接受相同的個人存取權杖與服務帳戶權杖，以及 OAuth 2.1 存取權杖。具備內建連接器的助理會自動探索授權伺服器，並要求您在瀏覽器中核准存取。OAuth 存取權杖綁定於 MCP 伺服器，REST 端點將會拒絕此類權杖。請參閱 [MCP](https://kanorio.com/zh-Hant/developers/mcp)。

## Content Delivery API

已發佈的內容為公開且經過邊緣快取，因此瀏覽器可直接呼叫。

- **來自其他來源的瀏覽器呼叫**，需將該來源加入 [網站設定 › 開發者](https://app.kanorio.com/settings/developer) 下的 **允許的來源**。任何連接埠上的 `localhost` 與 `127.0.0.1` 永遠被允許。CORS 控制瀏覽器可讀取的內容。這並非授權邊界，且未經預覽權杖，草稿內容絕不會被提供。
- **草稿預覽。** 在相同的設定頁面中，或使用 `POST /sites/{id}/preview-tokens` 建立 `knr_pv_` 預覽權杖。請從您的伺服器以 `X-Kanorio-Preview: knr_pv_...` 標頭發送。預覽回應會繞過快取且不會被儲存。

## Customer API

顧客無需密碼即可登入。網站擁有者可在 **網站設定 › 顧客帳戶** 中選擇啟用的方法；網站文件的 `customerAccess.methods` 會依顯示順序列出已啟用的方法。每種方法最終都會產生相同的 `knr_cat_` 工作階段權杖。

- **電子郵件驗證碼** (`email_code`，預設開啟) 與 **魔法連結** (`email_link`)：使用電子郵件地址呼叫 `POST /api/v1/customer/auth/challenge` 即可發送驗證碼。首先從 `GET /api/v1/customer/auth/protection` 取得機器人檢查：若使用內建檢查 (`provider: "kanorio"`)，請使用 `@kanorio/sdk` 中的 `solveProtectionChallenge` 解決並將欄位隨請求發送；若使用擁有者的 Turnstile、reCAPTCHA 或 hCaptcha 金鑰，請使用 `siteKey` 與 `action` 渲染該小工具，並將其權杖作為 `captchaToken` 發送。接著使用 `{ "method": "code", "email", "code" }` 或 `{ "method": "link", "token" }` 呼叫 `POST /api/v1/customer/auth/verify`。
- **Google** (`google`)：使用 `{ "method": "google", "baseUrl": <您的頁面來源> }` 呼叫 `POST /api/v1/customer/auth/oauth/start`，將會回傳供應商 URL；請將瀏覽器重新導向至該處。Kanorio 會託管同意畫面，並將瀏覽器導回帶有 `?handoff=` 的 `baseUrl`。請在 60 秒內進行交換：使用 `{ "method": "handoff", "token" }` 呼叫 `POST /api/v1/customer/auth/verify`。若 Google 帳戶的電子郵件未經驗證，顧客將改為收到電子郵件驗證碼，並被導向至帶有 `?email=&verify=1` 的頁面。
- **通行密鑰** (`passkey`)：呼叫 `POST /api/v1/customer/auth/passkey/options`，使用選項執行 `navigator.credentials.get()`，接著使用斷言與 `challengeId` 呼叫 `POST /api/v1/customer/auth/passkey/verify`。已登入的顧客可在 `/api/v1/customer/passkeys` 管理其通行密鑰。通行密鑰綁定於網站的主要網域，因此驗證程序必須在該來源上執行。

請在您的登入 UI 中處理來自 `POST /api/v1/customer/auth/challenge` 的這些回應：

| 代碼 | 處理方式 |
|---|---|
| `429 RATE_LIMITED` | 等待 `retryAfter` 秒後，讓顧客再次嘗試 |
| `403 BOT_PROTECTION_FAILED` | 取得新的挑戰（或重設小工具）並重新發送 |
| `503 SERVICE_UNAVAILABLE` | 登入功能暫時無法使用；顯示重試選項 |
| `503 SHARED_SENDER_PAUSED` | 此網站的電子郵件登入功能暫時暫停；請提供通行密鑰 (Passkeys) 或 Google 登入，或請顧客稍後再試 |

`200` 回應絕不會透露電子郵件是否已發送。Kanorio 會根據網站的登入流量調整機器人檢查：來自 `/auth/protection` 的挑戰可能會要求顯示小工具 (`visible: true`) 或更困難的內建謎題，因此請務必根據您取得的挑戰進行渲染，而非假設隱形流程。

在呼叫 Customer API 與受限的 Content Delivery API 讀取時，請將權杖作為 `Authorization: Bearer knr_cat_...` 發送。

顧客權杖僅代表該網站上的該名顧客。它無法讀取其他人的資料或呼叫 Management API。[`<kanorio-login>`](https://kanorio.com/zh-Hant/developers/elements) 元素會為您執行此流程。

## 輪替與撤銷

- **輪替**：從個人存取權杖的選單中進行輪替。Kanorio 會發出一個具有相同設定的新權杖，並讓舊權杖在您選擇的寬限期內（無、一小時或一天）繼續運作。若懷疑權杖外洩，請選擇「無」。
- **撤銷**：撤銷權杖以立即停止其運作。下一次使用該權杖的請求將會收到 `401 UNAUTHORIZED`。已完成的工作不會被復原。
- 使用任何權杖執行的活動，都會出現在網站的活動紀錄中，並歸類於該權杖擁有者或服務帳戶名稱下。

## 確保權杖安全

- 將權杖儲存在伺服器的環境變數或秘密管理服務中。切勿在權杖前加上 `NEXT_PUBLIC_` 或將其封裝在行動應用程式中。
- 切勿將權杖貼入 AI 對話中。真正的工具會從設定檔中讀取權杖。
- 每個工具使用一個權杖，每個整合使用一個服務帳戶，以便您能精確撤銷單一權杖。
- 給予每個權杖最窄的網站與權限範圍。
