> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 應用程式總覽

> 讓你的應用程式獲得在 Fluz 使用者帳戶上代為操作的權限——所牽涉的憑證、權限模型、權杖生命週期，以及下一步該讀哪一頁。

## 為什麼在這裡需要 OAuth

你的應用程式已能在**你自己的帳戶**上，執行 Fluz API 提供的一切功能。使用你的 API 金鑰產生權杖即可—請參見 [Authentication](/concepts/authentication) 與 [API credentials](/get-started/api-credentials)。

當帳戶不是你的時候，就需要 OAuth 應用程式。

當你想在客戶的錢包發卡、從他們連結的銀行帳戶扣款、讀取他們的交易或向他們撥款時，你需要該名使用者的明確授權——而且需要一種 Fluz 能驗證、限定範圍、設定到期並可撤銷的形式。這就是 OAuth 應用程式的意義：**你軟體的已註冊身分，加上一個將使用者同意轉換為你的伺服器可用權杖的同意機制。**

<Info>
  一旦你持有以客戶為範圍的權杖，API 便完全相同。用你自己的權杖呼叫 `createVirtualCard` 會在你的錢包建立卡片；用客戶權杖呼叫相同的 mutation 會在他們的錢包建立卡片。OAuth 改變的是\_你正在操作誰的帳戶\_，而不是你能做什麼。
</Info>

***

## 你需要嗎？

<Tabs>
  <Tab title="不需要——只操作你自己的帳戶">
    你在**你自己的 Fluz 帳戶**內發卡、購買禮品卡或移轉資金：撥款引擎、大量發卡、內部消費工具、ERP 同步。

    使用你的應用程式 API 金鑰直接呼叫 `generateUserAccessToken`。不需要 OAuth 應用程式、沒有同意畫面、沒有重新導向。從 [API credentials](/get-started/api-credentials) 開始。
  </Tab>

  <Tab title="需要——客戶帳戶">
    你在打造一個平台，**你的使用者各自擁有自己的 Fluz 帳戶**，而你代他們行事。

    你需要一個 OAuth 應用程式，且每位使用者都必須為你的應用程式授與一次 scopes。之後你就持有可刷新、以客戶為範圍的權杖。先閱讀 [Create an OAuth App](/create-an-o-auth-app)，再看 [Build a platform](/build-a-platform)。
  </Tab>

  <Tab title="你已經有了">
    你正在嵌入一個 [Fluz Widget](/developers/widgets)。

    Widget **就是** 一個 OAuth 應用程式——只是它在同意步驟提供了代管的前端介面，而不需要你自行打造重新導向流程。此頁所述的憑證、scopes 與權杖機制同樣適用。請參見 [Configure App Widget](/developers/configure-app-widget)。
  </Tab>
</Tabs>

***

## 三組憑證，各司其職

本章節最常見的困惑是：一個 Fluz 應用程式攜帶不只一組憑證，而且它們不能互換。

| Credential                           | 存放位置               | 用途                                                                                                     | 會離開你的伺服器嗎？                           |
| :----------------------------------- | :----------------- | :----------------------------------------------------------------------------------------------------- | :----------------------------------- |
| **API Key** / **API Secret**         | 你的應用程式 Overview 分頁 | 識別你的\_應用程式\_。在你自己的帳戶上產生權杖（`Authorization: Basic <API_KEY>`）並簽署 widget 的預先核准交易權杖。                       | 永不                                   |
| **Client ID** / **Client Secret**    | 你的應用程式 Overview 分頁 | 對\_授權伺服器\_識別你的應用程式。用在 authorize URL，以及交換或刷新代碼（`Authorization: Basic base64(client_id:client_secret)`）。 | Client ID 可公開；secret 永不              |
| **Access Token** / **Refresh Token** | 依使用者、依授權返回         | 以特定使用者和特定 scopes 在其帳戶上執行操作。                                                                            | 以 `Authorization: Bearer <token>` 傳送 |

<Warning>
  這裡的每個 secret 都能鑄造權限。洩漏 `apiSecret` 會讓他人能以你的平台名義簽署交易；洩漏 `client_secret` 會讓他人能以你的應用程式身分交換授權代碼。請將兩者都僅放在伺服器端，切勿出現在瀏覽器 bundle、行動裝置二進位檔或版本控制中。
</Warning>

***

## 權限模型

Fluz 在兩個層級強制執行權限，而應用程式的有效存取權是兩者的**交集**。

<Steps>
  <Step title="應用程式層級授與——天花板">
    設定於你的應用程式 **Permissions** 分頁。這是你的應用程式在任何使用者無關的情況下，所能請求的最大範圍。若你在 authorize URL 中放入未在此啟用的 scope，該 scope 將被靜默忽略——請求不會出錯，只是該 scope 不會被授與。

    有些 scopes 是由 Fluz 管控而非自行選取。`PCI_COMPLIANCE` 僅在應用層級授與，僅提供給已證明符合 PCI DSS 的開發者，且在產生權杖時不可請求。
  </Step>

  <Step title="使用者層級授與——地板">
    由最終使用者在同意畫面上設定。他們會看到你所請求的 scopes——以可讀的頂層標題群組呈現，而非原始列舉值——並同意它們。任何被拒絕的項目都不會被授與。
  </Step>

  <Step title="兩者都必須有效">
    在 `generateUserAccessToken` 時驗證，而非在呼叫時驗證。兩種授與都必須存在且未過期。因此，遭撤銷或失效的授與會表現為**權杖產生失敗**，而不是流程中途的權限錯誤——這通常是在先前運作正常的整合開始失效時，首先該檢查的地方。
  </Step>
</Steps>

依能力劃分的 scopes：

| Area  | Scopes                                                                              |
| :---- | :---------------------------------------------------------------------------------- |
| 資金來源  | `LIST_PAYMENT`, `MANAGE_PAYMENT`                                                    |
| 存款與提領 | `MAKE_DEPOSIT`, `MAKE_WITHDRAW`                                                     |
| 禮品卡   | `LIST_OFFERS`, `PURCHASE_GIFTCARD`, `REVEAL_GIFTCARD`, `LIST_PURCHASES`             |
| 虛擬卡   | `CREATE_VIRTUALCARD`, `EDIT_VIRTUALCARD`, `REVEAL_VIRTUALCARD`, `CREATE_SHARE_LINK` |
| 卡片資料  | `PCI_COMPLIANCE`（應用層級，Fluz 管控）                                                      |

使用 `getApplicationScopes` 讀取目前已授與的內容。完整參考： [Application Scopes](/application-scopes)。

<Note>
  **請求更少。** 較短的同意畫面轉換率更佳，而範圍更窄的權杖在外洩時能降低風險。只請求你眼前流程所需的內容，當需要更多時再產生新的權杖。
</Note>

***

## 生命週期，從頭到尾

以下每個步驟在本章節中都有深入頁面。這裡是地圖；那些頁面是疆域。

<Steps>
  <Step title="建立應用程式">
    在開發者控制台選擇 **Browse templates** 並加入 **OAuth Integration** 範本。為它命名、副標、描述——這三個欄位會出現在使用者的同意畫面上，所以請用給人看的語氣撰寫，而非你的議題追蹤器用語。

    → [Create an OAuth App](/create-an-o-auth-app)
  </Step>

  <Step title="進行設定">
    在 **Permissions** 分頁選擇你的 scope 天花板。在 **OAuth** 分頁設定 **Redirect URIs**（公開、不可含查詢參數、數量不拘）以及 **Webhook URLs**（可各自訂閱特定事件；未選事件的 URL 會成為全收）。在 **Overview** 加上頭像與標誌——沒有它們，同意畫面看起來不完整。

    → [Configure OAuth App](/configure-o-auth-app)
  </Step>

  <Step title="導引用戶進行授權">
    重新導向至 `/authorize` 並帶上 `response_type=code`、你的 `client_id`、一個已註冊的 `redirect_uri`、以空白分隔的 `scopes` 列表，以及可選擇性的 `state` 值（會原樣回傳給你）。

    → [Client-facing OAuth grant flow](/client-facing-o-auth-grant-flow)
  </Step>

  <Step title="接收授權代碼">
    在核准後，Fluz 會以 `code` 與你原先的 `state` 重新導向至你的 `redirect_uri`。若設定有誤，重新導向會帶有描述不匹配之處的錯誤訊息。
  </Step>

  <Step title="以授權代碼交換權杖">
    使用 `code` 與**完全相同的 `redirect_uri`** 呼叫 `/token/exchange`，並以 `Authorization: Basic base64(client_id:client_secret)` 驗證。你會拿回一個 `accessToken`、一個 `refreshToken`、到期時間戳，以及確認後的 scope 陣列。

    → [Exchanging an OAuth authorization code](/exchanging-an-o-auth-authorization-code)
  </Step>

  <Step title="刷新，不要重提同意">
    使用 `refresh_token` 與相同的 Basic auth 標頭呼叫 `/token/refresh`。存取權杖刻意設計為短效——大約十分鐘——而更新權杖約可維持一個月。請在背景靜默刷新；只有在更新權杖本身已過期或授與已被撤銷時，才再次將使用者帶回同意流程。

    → [Refreshing an OAuth accessToken](/refresh-o-auth-access-token)
  </Step>

  <Step title="上線">
    測試與正式是分離的環境，擁有分離的應用程式與分離的憑證。沒有任何東西會沿用——你需要在正式主機上再次註冊應用程式、重新導向 URI 與 webhook 端點。

    → [Deploying to Production](/deploying-to-production)
  </Step>
</Steps>

***

## 會咬人的規則

在開始之前值得內化，因為以下每一條都可能靜默或令人困惑地失敗。

<AccordionGroup>
  <Accordion title="Redirect URIs 必須完全相符——而且要兩次">
    你送往 `/authorize` 的 `redirect_uri` 必須已在應用程式註冊，且你送往 `/token/exchange` 的必須與你在 `/authorize` 使用的那個位元級相同。結尾斜線、`http` 與 `https`、主機大小寫都算。不要在 URI 本身註冊查詢參數——請用 `state` 傳遞情境。
  </Accordion>

  <Accordion title="未啟用的 scopes 會被忽略，而非被拒絕">
    若請求一個你未在 Permissions 分頁勾選的 scope，authorize 請求仍會成功——該 scope 會被丟棄。請務必閱讀交換回應中的 `scope` 陣列，並以它（而非你的請求）作為你能做什麼的事實依據。
  </Accordion>

  <Accordion title="授權代碼只能使用一次，且短效">
    立刻在伺服器端交換，且僅一次。若你的重新導向處理器可能被重放——使用者重新整理回呼頁面、連結預先擷取——請確保第二次嘗試不會破壞狀態。
  </Accordion>

  <Accordion title="Basic auth 是用配對連接後再 base64，而不是各自編碼">
    `Authorization: Basic <base64(client_id + ":" + client_secret)>`。請對連接後的字串進行編碼。交換步驟中多數的整合失敗都出在這裡。
  </Accordion>

  <Accordion title="`state` 是你唯一的回傳通道">
    重新導向是一次全新的瀏覽器導覽。若你需要知道是哪位使用者、哪個流程，或要回到哪個頁面，請在 `state` 放入簽章或可由伺服器查找的參照。不要在其中放入敏感資訊——它會經過使用者的瀏覽器。
  </Accordion>

  <Accordion title="權杖失敗通常是授與失敗">
    若 `generateUserAccessToken` 對昨天還能用的使用者開始失敗，請先檢查應用層級授與或使用者層級授與是否過期或被撤銷，再去檢查你的程式碼。
  </Accordion>
</AccordionGroup>

***

## OAuth 應用程式 vs. widgets

兩者都是應用程式，都使用上述的權限模型。差異在於誰負責打造同意介面。

|                      | OAuth 應用程式        | Widget               |
| :------------------- | :---------------- | :------------------- |
| 同意 UI                | 你打造重新導向流程         | Fluz 在你的頁面以 modal 呈現 |
| 使用者是否離開你的網站          | 會，前往 `/authorize` | 不會                   |
| 敏感資料（PAN、SSN、文件、PIN） | 由你處理，且你也需承擔相應範疇   | 由 Fluz 收集並加密         |
| 註冊與 KYC              | 由你自行打造，或透過 API    | 已包含在流程中              |
| 呈現控制權                | 完全掌控              | 侷限於品牌化               |
| 第一個可運行流程的時間          | 以天計               | 以小時計                 |

你可以混搭：透過 API 完成使用者註冊與 KYC，然後只在同意與敏感資料收集時開啟 widget。混合模式請見 [Embedded Widgets](/developers/widgets)。

***

## 下一步

<CardGroup cols={2}>
  <Card title="建立 OAuth 應用程式" icon="plus" href="/create-an-o-auth-app">
    從 OAuth Integration 範本註冊你的應用程式。
  </Card>

  <Card title="設定 OAuth 應用程式" icon="sliders" href="/configure-o-auth-app">
    Scopes、重新導向 URI、webhooks、品牌化。
  </Card>

  <Card title="用戶端授權流程" icon="user-check" href="/client-facing-o-auth-grant-flow">
    建立 authorize URL 並處理回呼。
  </Card>

  <Card title="交換授權代碼" icon="arrow-left-right" href="/exchanging-an-o-auth-authorization-code">
    將代碼轉換為 access token 與 refresh token。
  </Card>

  <Card title="刷新存取權杖" icon="refresh-cw" href="/refresh-o-auth-access-token">
    在不重新提示使用者的情況下維持授權。
  </Card>

  <Card title="部署到正式環境" icon="rocket" href="/deploying-to-production">
    針對正式主機重新註冊並上線。
  </Card>
</CardGroup>

<Info>
  正在打造一個平台，讓你的每位客戶都有一個 Fluz 帳戶嗎？[Build a platform](/build-a-platform) 端到端說明整個模式，而 [API Features](/features) 上的每項能力在連接帳戶上都以相同方式運作。
</Info>
