Ir al contenido

Autenticación ​

La API no tiene clave de API. Quien llama entra como una persona (correo y contraseña) y recibe dos tokens:

TokenDuraciónPara qué
accessTokencorta (expiresIn segundos; hoy 15 minutos)Va en todas las llamadas: Authorization: Bearer <accessToken>.
refreshTokenlarga (hasta 30 días; la institución puede reducirla)Solo para obtener un par nuevo en POST /auth/refresh.

Use siempre el valor de expiresIn de la respuesta en vez de fijar 15 minutos en su código.

Cuenta para la integración ​

Pida al curador de la institución que cree una cuenta solo para la integración (por ejemplo integracao@exemplo.org), con el rol mínimo necesario (vea Permisos). La persona recibe una invitación por correo y define la contraseña en la aplicación. Evite usar la cuenta de una persona del equipo: si se va, la integración se detiene.

Iniciar sesión ​

POST /auth/login con email y senha. La respuesta es la sesión:

bash
curl -X POST "$API/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"integracao@exemplo.org","senha":"********"}'
js
const r = await fetch(`${API}/auth/login`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ email: "integracao@exemplo.org", senha: process.env.SENHA }),
})
const sesion = await r.json()
python
import os, requests

r = requests.post(f"{API}/auth/login", json={"email": "integracao@exemplo.org", "senha": os.environ["SENHA"]})
sesion = r.json()
json
{
  "accessToken": "eyJhbGciOi...",
  "refreshToken": "q3v8...",
  "expiresIn": 900,
  "usuario": {
    "id": "0198a000-0000-7000-8000-000000000001",
    "email": "integracao@exemplo.org",
    "nome": "Integración Ejemplo",
    "locale": "es",
    "nationality": null,
    "vinculos": [
      { "papel": "CURADOR", "instituicaoId": "0198a000-0000-7000-8000-0000000000aa", "disciplinaId": null, "turmaId": null, "podeAvaliar": false, "podeCadastrar": false }
    ]
  }
}

usuario.vinculos muestra los roles de la cuenta y dónde valen (institución, asignatura o grupo). GET /auth/me devuelve la misma información en cualquier momento.

Llamar a la API ​

bash
curl "$API/auth/me" -H "Authorization: Bearer $TOKEN"

Renovar ​

Antes de que venza el accessToken (o al recibir 401 UNAUTHENTICATED), cambie el refreshToken:

bash
curl -X POST "$API/auth/refresh" -H "Content-Type: application/json" \
  -d '{"refreshToken":"q3v8..."}'

La respuesta es una sesión nueva, con un refreshToken nuevo. Reglas que importan a quien implementa:

  • Cada refreshToken sirve una sola vez. Guarde siempre el par más reciente.
  • Presentar de nuevo un refreshToken ya usado se trata como posible robo: se cierran todas las sesiones de la cuenta y hay que iniciar sesión otra vez con la contraseña. Por eso, en una integración con varios procesos, renueve en un solo lugar y comparta el token resultante; dos renovaciones simultáneas con el mismo refreshToken hacen que una falle con 401.
  • Si la renovación falla con 401, inicie sesión de nuevo con POST /auth/login.

Cerrar sesión ​

POST /auth/logout con el refreshToken cierra esa sesión. POST /auth/logout-todas (autenticada) cierra todas las sesiones de la cuenta.

Bloqueo por intentos ​

Errores de contraseña seguidos para el mismo correo bloquean nuevos intentos por un tiempo (por defecto: 5 fallos, bloqueo de 15 minutos). En ese caso, y cuando hay exceso de intentos desde el mismo origen, la respuesta es 429 RATE_LIMITED con retryAfterSeg y la cabecera Retry-After. No reintente en bucle: vea Paginación y límites. Contraseña incorrecta, correo inexistente y cuenta bloqueada reciben la misma respuesta 401, a propósito, para no revelar qué cuentas existen.

Guarde el secreto con cuidado ​

La contraseña y el refreshToken dan el mismo acceso que tendría la persona. Guárdelos en un almacén de secretos o en una variable de entorno del servidor, nunca en el código, el repositorio o los registros.

contato@presente.app.br