Cualquier sistema con API puede conectarse a jnfor. Si además publicas un manifiesto jnfor.json, tus usuarios solo pegan tu dominio en Conexiones › Conectar app y jnfor arma todo solo. Si agregas el intercambio de llave, ni siquiera tienen que copiarla.
1. Publica el manifiesto #
Sirve este archivo en https://tu-dominio.com/.well-known/jnfor.json:
{
"jnfor": 1,
"name": "Mi Plataforma",
"api_base": "https://tu-dominio.com/api/v1",
"auth": {
"type": "bearer",
"label": "Llave de API",
"help": "Panel › Integraciones › Llaves de API"
},
"test": "/me",
"notes": "Las fechas van en formato AAAA-MM-DD. Los montos están en MXN.",
"operations": [
{ "method": "GET", "path": "/pedidos", "description": "Lista pedidos. Parámetros: desde, hasta, estado." },
{ "method": "GET", "path": "/pedidos/{id}", "description": "Detalle de un pedido." },
{ "method": "GET", "path": "/clientes", "description": "Lista clientes. Parámetros: buscar." },
{ "method": "PUT", "path": "/pedidos/{id}", "description": "Cambia el estado de un pedido: {\"estado\":\"enviado\"}." }
],
"connect_url": "https://tu-dominio.com/integraciones/jnfor/autorizar",
"token_url": "https://tu-dominio.com/integraciones/jnfor/token"
}auth.type:none,bearer,header(agrega"header": "X-API-Key") obasic.test: una ruta GET sin parámetros obligatorios; jnfor la usa para comprobar la conexión.operations: describe bien cada ruta y sus parámetros. Es lo que lee el jn para saber qué pedir.connect_urlytoken_urlson opcionales y activan el botón «Conectar con Mi Plataforma».- Si ya tienes un
openapi.json, también sirve: jnfor lo detecta solo en las rutas comunes.
2. Intercambio de llave (opcional, recomendado) #
- El usuario pulsa Conectar en jnfor. jnfor lo envía a tu
connect_urlconclient=jnfor,callbackystate. - Tu plataforma confirma la sesión del usuario, le pregunta si autoriza a jnfor, crea una llave de API de solo lectura y guarda un
codede un solo uso (válido 5 minutos) asociado a esa llave. - Rediriges a
callback?state=…&code=…(ocallback?state=…&error=denegadosi no autorizó). - jnfor canjea el código en tu
token_urlde servidor a servidor y espera{"api_key": "…"}.
Ejemplo mínimo en PHP para tu plataforma:
// GET /integraciones/jnfor/autorizar
$usuario = requiere_sesion();
$callback = $_GET['callback'] ?? '';
$state = $_GET['state'] ?? '';
if (!preg_match('#^https://[a-z0-9.-]+/connect/callback$#i', $callback)) exit('Callback no válido');
if ($_SERVER['REQUEST_METHOD'] === 'POST' && csrf_valido()) {
$llave = crear_llave_api($usuario['id'], 'jnfor', 'lectura');
$code = bin2hex(random_bytes(24));
guardar_codigo($code, $llave, time() + 300); // un solo uso
header('Location: ' . $callback . '?' . http_build_query(['state' => $state, 'code' => $code]));
exit;
}
// muestra: «jnfor quiere consultar tus datos. [Autorizar] [Cancelar]»
// POST /integraciones/jnfor/token (llamada de servidor a servidor)
$in = json_decode(file_get_contents('php://input'), true);
$llave = canjear_codigo($in['code'] ?? ''); // null si no existe, expiró o ya se usó
header('Content-Type: application/json');
if (!$llave) { http_response_code(400); echo '{"error":"codigo_invalido"}'; exit; }
echo json_encode(['api_key' => $llave]);3. Botón «Conectar con jnfor» en tu panel #
También puedes iniciar el flujo desde tu plataforma:
<a href="https://jnfor.com/connect/start?manifest=https%3A%2F%2Ftu-dominio.com%2F.well-known%2Fjnfor.json">
Conectar con jnfor
</a>Seguridad #
- jnfor guarda la llave cifrada (AES-256-GCM) y nunca la muestra al jn ni la envía a la IA.
- Las conexiones de usuarios solo pueden apuntar a direcciones públicas.
- Por defecto el jn solo hace GET; cualquier POST, PUT, PATCH o DELETE requiere que el usuario permita cambios y confirme cada acción.