Saltar al contenido
Documentación · Tus propias API

Tus propias API

Una app puede pedir un token de acceso para una de tus API. Recibe un JWT firmado cuya audiencia es esa API y ninguna otra, y tu API lo comprueba con las claves publicadas de tu entorno, sin llamar a Usher. Un token para una API no sirve en otra.

Ponle nombre a la API

En Usher Console, abre el entorno y ve a Aplicaciones → Tus API → Añadir una API. Dale un nombre y un identificador: una dirección https://, como https://api.example.com, o un URN, como urn:example:api:notes. El identificador es lo que pide la app y lo que dice el claim aud del token (RFC 8707).

Después, asigna la API a las apps que la llaman, en API dentro de cada aplicación. Una app solo recibe tokens para las API que tiene asignadas, pida lo que pida. Si quitas una API, deja de dar tokens, y los que ya se han emitido caducan en pocos minutos.

Pídela

La app añade resource=<identifier> a su petición de autorización y a sus peticiones de token. Los SDK móviles lo hacen por ti:

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

Una app que llama a dos de tus API puede pedir las dos a la vez; la audiencia del token incluye entonces ambas.

Compruébalo en tu API

Comprueba el token de cada petición antes de fiarte de nada de lo que contenga:

  • La firma, con las claves del jwks_uri que figura en el documento de descubrimiento de tu entorno. Toma el algoritmo de la clave, nunca de la cabecera del token.
  • iss es exactamente el emisor de tu entorno. Fíjalo en tu configuración; nunca lo leas del token.
  • aud incluye el identificador de tu API. (Con el ámbito openid, también incluye la dirección de userinfo de tu entorno).
  • typ en la cabecera es at+jwt, para que nadie pueda hacer pasar un token de ID por un token de acceso.
  • exp no ha pasado. Los tokens de acceso duran 10 minutos; los SDK los renuevan por ti.

En Node.js, @usher/node lo hace todo:

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

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

Qué dice el token

Claim
subLa persona. Junto con iss, la clave con la que guardarla.
client_id, azpLa app que lo ha pedido.
scopeLo que la persona ha aceptado que haga la app.
email, email_verifiedCon el ámbito email: la dirección de la persona y si Usher ha verificado que es suya.
sidSu sesión.
orgCon el ámbito organization: su organización activa y su rol.

Personas que ya conoces

Si tu API ya tenía cuentas de antes, puedes encontrar la de una persona la primera vez que llega con un token de Usher: búscala por email, solo cuando email_verified sea true, y guarda iss y sub en su cuenta desde ese momento. A partir de entonces, búscala por iss y sub, nunca por el correo electrónico: una dirección puede cambiar de manos, y un sujeto, nunca.