Apps OAuth de terceros
Conecta tu app con autorización del usuario, PKCE S256 y tokens rotativos, sin pedir API keys.
OAuth sirve cuando tu aplicación debe operar un workspace que pertenece a otra persona. La persona autoriza los scopes que ve en Meteor; tu app recibe un token de acceso temporal. Nunca le pidas ni captures su API key.
Meteor implementa OAuth 2.0 Authorization Code con PKCE S256 obligatorio. El access token se usa como Bearer para la misma API pública; dura una hora. El refresh token dura 30 días y rota en cada uso.
Antes de redirigir
En el workspace dueño de tu integración, abre Ajustes → Desarrolladores → Apps OAuth y registra la app. Guarda el client_id. Si eliges una app confidencial, guarda también el client_secret: Meteor lo muestra solo al crearla o al rotarlo.
- Registra cada
redirect_uricompleto. Meteor compara la URL de retorno exactamente; no acepta comodines ni fragmentos (#). - El callback debe usar HTTPS, salvo
localhost,127.0.0.1o::1durante desarrollo. - Declara solo los scopes mínimos. Los scopes de partner no se pueden asignar a una app OAuth.
- Elige pública para una SPA o app nativa que no puede proteger un secreto. Elige confidencial solo si el canje ocurre en tu servidor.
Redirigir al consentimiento
Genera por usuario un state impredecible y un code_verifier PKCE de 43 a 128 caracteres. Guarda ambos en la sesión de tu app. Calcula code_challenge = base64url(SHA-256(code_verifier)) y redirige el navegador a la pantalla de Meteor:
import { createHash, randomBytes } from 'node:crypto';
import { OAuth } from '@meteor.ia/sdk';
const verifier = randomBytes(48).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const state = randomBytes(24).toString('base64url');
// Guarda verifier y state en la sesión antes de redirigir.
const oauth = new OAuth();
const url = oauth.authorizeUrl({
clientId: process.env.MET_OAUTH_CLIENT_ID!,
redirectUri: 'https://tu-app.example.com/oauth/callback',
scope: ['runs:execute', 'contacts:read'],
state,
codeChallenge: challenge,
});
res.redirect(url);
La persona inicia sesión en Meteor si hace falta y ve el nombre de tu app, su sitio y los scopes solicitados. Si acepta, Meteor redirige a tu redirect_uri con code y el mismo state. Si rechaza, vuelve con error=access_denied.
Canjear el código en tu servidor
En el callback, primero compara state con el que guardaste y luego canjea el código. Envía siempre el mismo redirect_uri y el code_verifier original. El código es de un solo uso y vence en 60 segundos.
const { access_token, refresh_token, expires_in, scope } = await oauth.exchangeCode({
clientId: process.env.MET_OAUTH_CLIENT_ID!,
clientSecret: process.env.MET_OAUTH_CLIENT_SECRET, // solo apps confidenciales
code: String(req.query.code),
redirectUri: 'https://tu-app.example.com/oauth/callback',
codeVerifier: session.pkceVerifier,
});
// Cifra refresh_token al guardarlo. access_token es una key met_ temporal.
No envíes el client_secret, el code_verifier, el código ni el refresh token al navegador, registros o analítica. El token no incorpora un workspace_id: conserva en tu propio vínculo de instalación el workspace al que operará cada conexión si la ruta que usas lo requiere.
Llamar la API y renovar
El access_token es un Bearer token para los scopes aprobados. Úsalo con la API REST o el SDK; para rutas que lo necesitan, configura el workspaceId de esa instalación.
import Met from '@meteor.ia/sdk';
const met = new Met(access_token, { workspaceId: installation.workspaceId });
const run = await met.runs.create({ input: 'Resume los leads de hoy' });
Antes de que venza, o tras una respuesta de token expirado, renueva desde tu servidor. Cada refresh emite un refresh token nuevo: reemplaza el anterior de forma atómica. Reusar un refresh ya consumido revoca todo el grant por seguridad.
const renewed = await oauth.refresh({
clientId: process.env.MET_OAUTH_CLIENT_ID!,
clientSecret: process.env.MET_OAUTH_CLIENT_SECRET,
refreshToken: installation.refreshToken,
});
// Guarda renewed.access_token y renewed.refresh_token juntos.
Revocar y rotar
Una persona puede revocar tu app desde Ajustes → Desarrolladores → Apps OAuth. Tu app también puede revocar un access o refresh token; revocar un refresh token invalida el grant completo:
await oauth.revoke(installation.refreshToken, {
clientId: process.env.MET_OAUTH_CLIENT_ID!,
clientSecret: process.env.MET_OAUTH_CLIENT_SECRET,
});
Para apps confidenciales, rota el client_secret desde la misma pantalla. La rotación normal conserva el secreto anterior por 24 horas para desplegar el nuevo; usa la invalidación inmediata solo si se filtró.
Si tu workspace dueño ya usa webhooks salientes, puedes suscribirte a app.authorized y app.revoked con integrations:read. Esos eventos llegan al workspace que registró la app e incluyen client_id, workspace_id, scopes y grant_id, sin datos personales.
Límites actuales
El servidor de autorización no publica todavía metadata OAuth en /.well-known/oauth-authorization-server ni registro dinámico de clientes. Configura manualmente las URLs que documenta esta guía; no intentes descubrirlas desde el dominio.