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:
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 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_urique figura en el documento de descubrimiento de tu entorno. Toma el algoritmo de la clave, nunca de la cabecera 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 ámbitoopenid, también incluye la dirección de userinfo de tu entorno).typen la cabecera esat+jwt, para que nadie pueda hacer pasar un token de ID por un token de acceso.expno ha pasado. 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, la clave con la que guardarla. |
client_id, azp | La app que lo ha pedido. |
scope | Lo que la persona ha aceptado que haga la app. |
email, email_verified | Con el ámbito email: la dirección de la persona y si Usher ha verificado que es suya. |
sid | Su sesión. |
org | Con 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.