OrbitSenderDocs

Gerenciar, revogar e boas práticas

Como remover vínculos, revogar tokens, tratar os erros do fluxo OAuth, respeitar rate limits e proteger sua integração.

Esta página é o guia de operação e segurança da sua integração: como você (parceiro) e o usuário revogam acessos, o que significa cada erro do fluxo OAuth, como lidar com rate limits e a checklist de boas práticas.

Gerenciar contas vinculadas (Portal do Dev)

No Portal do Dev (dentro do app, em https://app.orbitsender.com), a aba Contas Vinculadas mostra quais contas autorizaram cada um dos seus apps.

A partir dessa tela você pode remover o vínculo de uma conta. A remoção é imediata:

  • revoga a autorização do usuário para aquele app;
  • invalida na hora os tokens (access e refresh) daquela conta.

Revogação é instantânea

Ao remover um vínculo, os tokens deixam de funcionar imediatamente. Qualquer chamada seguinte com aquele access_token retorna erro de autenticação, e o refresh_token da família também para de valer.

O usuário também controla o acesso

O acesso é sempre do usuário. No app, em Apps Conectados, o próprio usuário pode desconectar o seu app quando quiser — sem passar por você.

Revogar de qualquer lado (você pelo Portal do Dev, ou o usuário em Apps Conectados) mata os tokens imediatamente. Depois disso, para voltar a operar em nome daquele usuário é preciso passar de novo pela tela de consentimento (/authorize).

Você também pode revogar um token específico via endpoint padrão RFC 7009:

curl -X POST https://api.orbitsender.com/api/oauth/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=orb_rt_..."

revoke sempre responde 200

O endpoint /api/oauth/revoke responde sempre 200, independentemente de o token existir ou já estar inválido. Não use a resposta para inferir a validade de um token.

Erros do fluxo OAuth

Os erros seguem a RFC 6749 no campo error. No /authorize, o erro pode voltar como query param no redirect_uri ({redirect_uri}?error=...&state=...); no /token, vem no corpo JSON da resposta.

errorQuando aconteceO que fazer
invalid_requestParâmetro ausente ou malformado.Revise os parâmetros obrigatórios (response_type, client_id, redirect_uri, code_challenge, etc.).
unauthorized_clientApp inexistente ou ainda não aprovado.Confirme o client_id e se o app está com status approved (Criar app).
invalid_scopeScope solicitado não foi aprovado.Peça apenas scopes aprovados para o app (Scopes).
invalid_clientFalha na validação do client_secret.Verifique o secret do app confidential; rotacione no portal se necessário.
invalid_grantcode/refresh_token inválido, expirado, já usado, ou PKCE inválido.Reinicie o fluxo de autorização; garanta o code_verifier correto e não reutilize codes/refresh.
unsupported_grant_typegrant_type não suportado.Use authorization_code ou refresh_token.
invalid_accountConta sem tenant tentou consentir.O usuário precisa de uma conta com tenant ativo para autorizar.
access_deniedO usuário recusou o consentimento na tela /authorize.Volta no redirect como {redirect_uri}?error=access_denied&state=.... Trate como cancelamento normal — sem retry automático.

Reuse de refresh token revoga a família

O refresh_token é rotativo: cada uso invalida o anterior. Reapresentar um refresh já usado é tratado como detecção de reuse e revoga a família inteira de tokens. Sempre substitua o refresh guardado pelo novo retornado a cada troca. Veja Gerar token.

Rate limits

Há limites por app tanto nos endpoints de OAuth quanto na API externa. Ao estourar um limite, a API responde HTTP 429 com corpo { "success": false, "error": "rate_limited" }, o header Retry-After (em segundos até liberar) e os headers RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset (limite, restante e segundos até a janela resetar).

Grupo de endpointsLimiteJanelaBucket (chave do limite)
POST /api/oauth/token30 req60 spor client_id
POST /api/oauth/revoke30 req60 spor IP (o corpo do revoke não tem client_id)
GET /api/oauth/authorize (consentimento)60 req60 spor IP
/api/external/* (todas as chamadas de recurso)300 req60 spor credencial (api-key ou access token)

Trate o 429 com backoff (idealmente exponencial) e re-tentativas espaçadas. Não faça retry imediato em loop.

async function chamarComBackoff(fn: () => Promise<Response>, tentativas = 4) {
  let espera = 1000; // ms
  for (let i = 0; i < tentativas; i++) {
    const res = await fn();
    if (res.status !== 429) return res;
    await new Promise((r) => setTimeout(r, espera));
    espera *= 2; // backoff exponencial
  }
  throw new Error("Rate limit persistente (429)");
}

Limites do portal

No Portal do Dev há também limites operacionais: no máximo 5 apps por parceiro e no máximo 2 envios para revisão por dia.

Boas práticas de segurança

  • Guarde o client_secret só no servidor. Nunca exponha em app público, mobile ou front-end. App public não tem secret — use PKCE.
  • Use state como anti-CSRF em toda ida ao /authorize e valide-o no retorno (compare com o valor que você gerou).
  • redirect_uri sempre em HTTPS e com exact-match a uma URI registrada no app — sem barra, porta ou query a mais.
  • Use PKCE (S256), obrigatório para apps public e recomendado sempre. Veja PKCE.
  • Rotacione e armazene o refresh_token com segurança e sempre troque pelo novo retornado a cada refresh (o anterior deixa de valer).
  • Trate 401 (access token expirado) fazendo refresh do token; trate 403 (scope faltando) revisando os scopes consentidos.
  • Peça o mínimo de scopes. Menos permissão = revisão mais rápida e menor superfície de risco. Consulte a referência de scopes.

Nesta página