跳至內容
文件 · 你自己的 API

你自己的 API

App 可以要求取得你其中一個 API 的存取權杖。它會得到一個已簽署的 JWT,其對象就是該 API,別無其他;你的 API 則以環境公開發布的密鑰檢查它,不必呼叫 Usher。用於某個 API 的權杖,在另一個 API 上毫無用處。

為 API 命名

在 Usher Console 中打開環境,然後選擇 應用程式 → 你的 API → 加入 API。為它設定名稱和識別碼:一個 https:// 地址(例如 https://api.example.com),或一個 URN(例如 urn:example:api:notes)。識別碼就是 App 所要求的內容,也是權杖的 aud 宣告中寫的值(RFC 8707)。

接著,把 API 提供給呼叫它的 App:在每個應用程式的 API 中設定。不論 App 要求什麼,它都只會取得已獲提供之 API 的權杖。移除某個 API 後,就不會再為它發出權杖;已經發出的權杖也會在幾分鐘內到期。

要求權杖

App 會在授權請求和權杖請求中加上 resource=<identifier>。流動裝置 SDK 會替你完成這件事:

swift
let usher = UsherClient(configuration: .init(
    issuer: URL(string: "https://login.example.com")!,
    clientID: "…",
    redirectURI: URL(string: "com.example.notes:/oauth/callback")!,
    resources: ["urn:example:api:notes"]))

var request = URLRequest(url: URL(string: "https://api.example.com/notes")!)
try await usher.authorize(&request)   // Authorization: Bearer <a JWT for the Notes API>
kotlin
val usher = Usher.client(context, UsherConfiguration(
    issuer = "https://login.example.com",
    clientId = "…",
    redirectUri = "com.example.notes:/oauth/callback",
    resources = listOf("urn:example:api:notes")))

會呼叫你兩個 API 的 App,可以一次要求兩者;這時權杖的對象會同時列出兩者。

在你的 API 中檢查

在信任權杖中的任何內容之前,請先檢查每個請求的權杖:

  • 簽名:以環境探索文件中 jwks_uri 的密鑰檢查。演算法要取自密鑰,絕不可取自權杖的標頭。
  • iss 必須完全等於你環境的簽發者。請在設定中固定這個值,絕不要從權杖中讀取。
  • aud 包含你 API 的識別碼。(使用 openid 範圍時,它也會列出你環境的 userinfo 地址。)
  • 標頭中的 typ 為 at+jwt,因此 ID 權杖無法被冒充成存取權杖。
  • exp 尚未過期。存取權杖有效 10 分鐘;SDK 會替你重新整理。

在 Node.js 中,@usher/node 會處理這一切:

TypeScript
import { createVerifier } from '@usher/node'

const usher = await createVerifier({
  issuer: 'https://login.example.com',
  audience: 'urn:example:api:notes',
})

const claims = await usher.accessToken(bearerToken) // throws if any check fails

在 ASP.NET Core 中:

csharp
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.Authority = "https://login.example.com"; // discovery and keys come from here
        o.MapInboundClaims = false;
        o.TokenValidationParameters = new()
        {
            ValidIssuer = "https://login.example.com",
            ValidAudience = "urn:example:api:notes",
            ValidTypes = ["at+jwt"],
        };
    });

權杖的內容

宣告
sub用户本人。與 iss 組合起來,就是保存這位用户的依據。
client_id、azp提出要求的 App。
scope用户同意 App 可以做的事。
email、email_verified使用 email 範圍時:用户的電郵地址,以及 Usher 是否已證實該地址屬於他們。
sid他們的登入工作階段。
org使用 organization 範圍時:他們目前使用中的組織與角色。

你已經認識的用户

如果你的 API 先前已經有自己的帳户,你可以在用户第一次帶著 Usher 權杖到來時找到他們的帳户:按 email 查詢,但只在 email_verified 為 true 時才這麼做,並從那時起在他們的帳户上保存 iss 和 sub。之後,請按 iss 和 sub 尋找他們,絕不要按電郵:電郵地址可能會易主,主體(subject)則永遠不會。