Ir para o conteúdo

Autenticação ​

A API não tem chave de API. Quem chama entra como uma pessoa (e-mail e senha) e recebe dois tokens:

TokenDuraçãoPara quê
accessTokencurta (expiresIn segundos; hoje 15 minutos)Vai em todas as chamadas: Authorization: Bearer <accessToken>.
refreshTokenlonga (até 30 dias; a instituição pode reduzir)Só para obter um par novo em POST /auth/refresh.

Use sempre o valor de expiresIn da resposta em vez de fixar 15 minutos no seu código.

Conta para a integração ​

Peça ao curador da instituição que crie uma conta só para a integração (por exemplo integracao@exemplo.org), com o papel mínimo necessário (veja Permissões). A pessoa recebe um convite por e-mail e define a senha no aplicativo. Evite usar a conta de uma pessoa da equipe: se ela sair, a integração para.

Entrar ​

POST /auth/login com email e senha. A resposta é a sessão:

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 sessao = await r.json()
python
import os, requests

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

usuario.vinculos mostra os papéis da conta e onde valem (instituição, disciplina ou turma). GET /auth/me devolve a mesma informação a qualquer momento.

Chamar a API ​

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

Renovar ​

Antes de o accessToken vencer (ou ao receber 401 UNAUTHENTICATED), troque o refreshToken:

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

A resposta é uma sessão nova, com um refreshToken novo. Regras que valem para quem implementa:

  • Cada refreshToken serve uma única vez. Guarde sempre o par mais recente.
  • Apresentar de novo um refreshToken já usado é tratado como possível roubo: todas as sessões da conta são encerradas e é preciso entrar de novo com a senha. Por isso, em uma integração com vários processos, renove em um só lugar e compartilhe o token resultante; duas renovações ao mesmo tempo com o mesmo refreshToken fazem uma delas falhar com 401.
  • Se a renovação falhar com 401, entre de novo em POST /auth/login.

Sair ​

POST /auth/logout com o refreshToken encerra aquela sessão. POST /auth/logout-todas (autenticada) encerra todas as sessões da conta.

Bloqueio por tentativas ​

Erros de senha seguidos para o mesmo e-mail bloqueiam novas tentativas por um tempo (padrão: 5 falhas, bloqueio de 15 minutos). Nesse caso, e quando há excesso de tentativas vindas da mesma origem, a resposta é 429 RATE_LIMITED com retryAfterSeg e o cabeçalho Retry-After. Não tente de novo em laço: veja Paginação e limites. Senha errada, e-mail inexistente e conta travada recebem a mesma resposta 401, de propósito, para não revelar quais contas existem.

Guarde o segredo com cuidado ​

A senha e o refreshToken dão o mesmo acesso que a pessoa teria. Guarde-os em um cofre de segredos ou em variável de ambiente do servidor, nunca no código, no repositório ou em logs.

contato@presente.app.br