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:
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>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_urique figura en el documento de descubrimiento de tu entorno. Toma el algoritmo de la clave, nunca del encabezado del token. isses exactamente el emisor de tu entorno. Fíjalo en tu configuración; nunca lo leas del token.audincluye el identificador de tu API. (Con el alcanceopenid, también incluye la dirección de userinfo de tu entorno).typen el encabezado esat+jwt, para que no se pueda hacer pasar un token de ID por un token de acceso.exptodavía no pasó. Los tokens de acceso duran 10 minutos; los SDK los renuevan por ti.
En Node.js, @usher/node lo hace todo:
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 failsEn ASP.NET Core:
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 | |
|---|---|
sub | La persona. Junto con iss, es lo que debes guardar para identificarla. |
client_id, azp | La app que lo pidió. |
scope | Lo que la persona aceptó que la app puede hacer. |
email, email_verified | Con el alcance email: la dirección de la persona, y si Usher comprobó que es suya. |
sid | Su sesión de inicio de sesión. |
org | Con 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.