Ir 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 nada más, y tu API lo comprueba con las claves publicadas de tu entorno, sin llamar a Usher. Un token para una API no sirve para otra.

Ponle nombre a la API

En Usher Console, abre el entorno y luego Aplicaciones → Tus API → Agregar 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 indica el claim aud del token (RFC 8707).

Luego 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 recibir tokens para ella; los que ya se emitieron vencen en pocos minutos.

Pide el token

La app agrega resource=<identifier> a su solicitud de autorización y a sus solicitudes 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 ambas a la vez; en ese caso, la audiencia del token incluye las dos.

Compruébalo en tu API

Comprueba el token de cada solicitud antes de confiar en cualquier dato 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 del encabezado 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 alcance openid, también incluye la dirección de userinfo de tu entorno).
  • typ en el encabezado es at+jwt, para que no se pueda hacer pasar un token de ID por un token de acceso.
  • exp todavía no pasó. 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, es lo que debes guardar para identificarla.
client_id, azpLa app que lo pidió.
scopeLo que la persona aceptó que la app puede hacer.
email, email_verifiedCon el alcance email: la dirección de la persona, y si Usher comprobó que es suya.
sidSu sesión de inicio de sesión.
orgCon el alcance 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 a partir de ese momento. Después, búscala por iss y sub, nunca por correo electrónico: una dirección puede cambiar de dueño, un sujeto nunca.