Zum Inhalt springen
Dokumentation · Deine eigenen APIs

Deine eigenen APIs

Eine App kann ein Access-Token für eine deiner APIs anfordern. Sie bekommt ein signiertes JWT, dessen Audience genau diese API ist und sonst nichts, und deine API prüft es mit den veröffentlichten Schlüsseln deiner Umgebung, ohne Usher aufzurufen. Ein Token für die eine API nützt bei einer anderen nichts.

Gib der API einen Namen

Öffne in Usher Console die Umgebung und dann Anwendungen → Deine APIs → API hinzufügen. Gib ihr einen Namen und einen Bezeichner: eine https://-Adresse wie https://api.example.com oder eine URN wie urn:example:api:notes. Der Bezeichner ist das, was die App anfordert und was im aud-Claim des Tokens steht (RFC 8707).

Gib die API dann den Apps, die sie aufrufen: unter APIs bei jeder Anwendung. Eine App bekommt nur Tokens für die APIs, die ihr zugewiesen sind, ganz gleich, was sie anfordert. Entfernst du eine API, werden für sie keine Tokens mehr ausgestellt; die bereits ausgegebenen laufen innerhalb weniger Minuten ab.

Fordere sie an

Die App fügt ihrer Autorisierungsanfrage und ihren Token-Anfragen resource=<identifier> hinzu. Die mobilen SDKs erledigen das für dich:

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")))

Eine App, die zwei deiner APIs aufruft, kann beide auf einmal anfordern; die Audience des Tokens nennt dann beide.

Prüfe es in deiner API

Prüfe das Token jeder Anfrage, bevor du irgendetwas darin vertraust:

  • Die Signatur, mit den Schlüsseln unter der jwks_uri im Discovery-Dokument deiner Umgebung. Nimm den Algorithmus aus dem Schlüssel, nie aus dem Header des Tokens.
  • iss ist genau der Issuer deiner Umgebung. Leg ihn in deiner Konfiguration fest; lies ihn nie aus dem Token.
  • aud enthält den Bezeichner deiner API. (Mit dem Scope openid steht dort außerdem die Userinfo-Adresse deiner Umgebung.)
  • typ im Header ist at+jwt, damit sich ein ID-Token nicht als Access-Token ausgeben lässt.
  • exp ist nicht überschritten. Access-Tokens gelten 10 Minuten; die SDKs erneuern sie für dich.

In Node.js erledigt @usher/node all das:

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

In 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"],
        };
    });

Was im Token steht

Claim
subDie Person. Zusammen mit iss der Schlüssel, unter dem du sie speicherst.
client_id, azpDie App, die angefragt hat.
scopeWas die App laut Zustimmung der Person tun darf.
email, email_verifiedMit dem Scope email: die Adresse der Person und ob Usher bestätigt hat, dass sie ihr gehört.
sidIhre Anmeldesitzung.
orgMit dem Scope organization: ihre aktive Organisation und Rolle.

Menschen, die du schon kennst

Hat deine API schon Konten aus der Zeit davor, kannst du das Konto einer Person finden, wenn sie zum ersten Mal mit einem Usher-Token kommt: Such sie anhand von email, aber nur, wenn email_verified den Wert true hat, und speichere ab dann iss und sub an ihrem Konto. Danach findest du sie über iss und sub, nie über die E-Mail-Adresse: Eine Adresse kann den Besitzer wechseln, ein Subject nie.