Auth21

Auth21 · Consola

Manual OAuth & Apps

O que configurar em OAuth & Apps e trechos prontos (Hosted e Bridge) em JavaScript — sem PHP e sem guia de instalação do servidor.

O que é este guia

Este texto é o manual de utilização da Auth21 para quem configura OAuth na consola e integra um site ou app. Explica o que fazer em OAuth & Apps (oauth-manage) e dá exemplos de código no teu servidor em JavaScript (Node.js) — não é documentação de instalação do servidor Auth21 nem guia em PHP.


Modos de login (na consola)

ModoOnde está a password do utilizadorO que escolhes na consola
HostedNa Auth21O utilizador faz login nos ecrãs da Auth21 (registo / login na tua org).
BridgeNo teu sistemaIndicas o endpoint bridge (URL no teu site) e o segredo HMAC; depois do login no teu site, o teu backend notifica a Auth21 para fechar o fluxo OAuth.
EnterpriseReservadoFluxo OAuth “normal” usa Hosted ou Bridge.

Na consola — OAuth & Apps

Abre a página OAuth & Apps na consola (menu / atalho oauth-manage). Tudo o que precisas para alinhar com o teu site está neste ecrã.

1) Configuração do tenant

Modo de login — escolhe Bridge, Hosted ou Enterprise (conforme a tua conta). A descrição no ecrã resume a diferença.

Se escolheres Bridge:

  • Endpoint bridge — URL pública (HTTPS) no teu domínio para onde a Auth21 redirecciona o utilizador com request_id e return_to. É aí que o teu site trata do login e depois envia o callback assinado (ver secção Bridge).
  • Segredo HMAC — palavra-passe partilhada entre a consola e o teu backend; usa o mesmo valor ao calcular a assinatura. Se deixares em branco ao guardar, a consola mantém o segredo anterior.
  • Confiar no bridge — se estiver activo, a Auth21 pode emitir o código OAuth sem mostrar o ecrã de consentimento (quando fizer sentido para a tua política).

Marca nos ecrãs públicos — nome, cor e logótipo opcionais para os ecrãs de login/consentimento da Auth21 para este tenant.

Clica Guardar tenant para aplicar.

2) Nova aplicação OAuth

Cada site ou aplicação cliente precisa de uma aplicação OAuth (um client_id).

  • Nome — só para identificares na consola.
  • Redirect URI base — deve corresponder à origem do teu site onde vais tratar o regresso do login (ex.: https://loja.exemplo.com ou o path exacto do callback, conforme o teu arranjo). Tem de bater com o que usas no SDK / redirect no browser.

Após criar, a consola mostra client_id e client_secret. O segredo pode aparecer só uma vez — guarda-o em cofre / variáveis de ambiente no teu servidor, nunca em JavaScript público.

Em modo Hosted, podes ainda gerir utilizadores com conta na Auth21 na mesma área, se a tua instalação o permitir.


Depois da consola — modo Hosted

Com o tenant em Hosted e a aplicação OAuth criada, no teu projeto precisas de: (1) carregar o SDK no browser, (2) uma página de callback no teu domínio, (3) um endpoint no teu servidor que troca o authorization_code por tokens — esse passo usa o client_secret e não pode correr no browser.

Substitui ISSUER pela URL base da Auth21 (a mesma que usas para abrir a consola, sem path extra, ex. https://auth.exemplo.com).

Browser — botão e callback

<script src="ISSUER/sdk/auth21.js"></script>
<script>
  Auth21.init({
    issuer: 'ISSUER',
    clientId: 'O_TEU_CLIENT_ID',
    redirectUri: 'https://teu-dominio.com/caminho/callback',
    scope: 'openid profile email'
  });
</script>
<button type="button" onclick="Auth21.login().catch(function(e){ alert(e.message); })">
  Entrar
</button>

Na página de callback, lê o resultado com Auth21.readCallback() e envia code, code_verifier e redirect_uri ao teu backend (por exemplo com fetch('/api/auth21/token', { method: 'POST', ... })).

Telemóvel — QR e leitura (tudo na Auth21)

Quando o fluxo OAuth está em curso, o identificador do pedido pendente (pend no hosted, request_id no bridge) tem 64 caracteres hexadecimais. A Auth21 fornece:

  • Leitura no telemóvelISSUER/mobile-handoff?token=ID (o telemóvel abre e segue para login hosted ou para o teu bridge).
  • Página com QR + cópia do linkISSUER/mobile-handoff-qr?token=ID (podes mostrar no desktop; o utilizador escaneia com a câmara).
  • Iframe compactoISSUER/mobile-handoff-qr?token=ID&embed=1 para embutir no teu site sem texto extra.

Na consola OAuth & Apps, por aplicação podes desactivar estes endereços (migração add_oauth_mobile_qr_handoff.sql). O ID deixa de ser válido para estes URLs quando o fluxo termina.

<!-- No teu HTML, TOKEN = id do pedido em curso -->
<iframe title="Continuar no telemóvel" width="280" height="320"
  src="ISSUER/mobile-handoff-qr?token=TOKEN&embed=1"></iframe>

Servidor — trocar o código por tokens (Node.js)

Exemplo com fetch (Node 18+). O segredo vem só de variável de ambiente.

// POST /api/auth21/token — corpo JSON: { code, code_verifier, redirect_uri }
import 'dotenv/config';

const ISSUER = process.env.AUTH21_ISSUER.replace(/\/$/, '');
const CLIENT_ID = process.env.AUTH21_CLIENT_ID;
const CLIENT_SECRET = process.env.AUTH21_CLIENT_SECRET;

export async function auth21ExchangeToken({ code, code_verifier, redirect_uri }) {
  const res = await fetch(`${ISSUER}/token.php`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-OAuth-Backend': '1',
    },
    body: JSON.stringify({
      grant_type: 'authorization_code',
      code,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      redirect_uri,
      code_verifier,
    }),
  });
  return res.json();
}

Com o access_token, podes chamar o perfil em GET ISSUER/userinfo.php?client_id=... com header Authorization: Bearer … a partir do teu backend.


Depois da consola — modo Bridge

Com o tenant em Bridge, na consola já definiste o Endpoint bridge e o Segredo HMAC. Fluxo resumido:

  1. O utilizador inicia o login OAuth na Auth21.
  2. A Auth21 redirecciona o browser para o teu Endpoint bridge com request_id e return_to (URL do serviço Auth21 onde deves enviar o resultado). Para o utilizador continuar no telemóvel sem criares página própria, usa ISSUER/mobile-handoff?token= + o mesmo request_id (ver secção Hosted — Telemóvel).
  3. No teu site, autenticas o utilizador como já fazes hoje.
  4. O teu servidor monta o JSON de identidade, codifica em Base64, calcula a assinatura HMAC-SHA256 em hex minúsculas sobre a mesma string Base64 que envias no parâmetro payload.
  5. Redireccionas o browser para return_to com request_id, payload e signature (ou equivalente em POST, conforme a tua implementação).

Exemplo completo (Node.js)

Adapta à tua framework; o essencial é o cálculo de payload + signature e o redirect final.

import crypto from 'crypto';
import 'dotenv/config';

const BRIDGE_SECRET = process.env.AUTH21_BRIDGE_HMAC_SECRET;

export function buildAuth21BridgeRedirect(requestId, returnToUrl, user) {
  const payloadObj = {
    timestamp: Math.floor(Date.now() / 1000),
    email: user.email,
    user_id: user.id,
    name: user.name,
  };
  const payloadJson = JSON.stringify(payloadObj);
  const payloadB64 = Buffer.from(payloadJson, 'utf8').toString('base64');
  const signature = crypto
    .createHmac('sha256', BRIDGE_SECRET)
    .update(payloadB64, 'utf8')
    .digest('hex');

  const url = new URL(returnToUrl);
  url.searchParams.set('request_id', requestId);
  url.searchParams.set('payload', payloadB64);
  url.searchParams.set('signature', signature);
  return url.toString();
}

// Depois de autenticares o utilizador no teu /auth21-bridge:
// const target = buildAuth21BridgeRedirect(req.query.request_id, req.query.return_to, currentUser);
// res.redirect(302, target);

SDK no browser

O ficheiro auth21.js deve ser carregado a partir da mesma origem pública da tua Auth21: <script src="ISSUER/sdk/auth21.js"></script>. O endpoint de token não aceita chamadas directas do browser com segredo — por isso o callback envia os dados ao teu servidor, como nas secções acima.


Referência — contrato Bridge (HMAC)

Detalhe técnico do callback para validares a tua implementação (independente da linguagem).

Parâmetros enviados à Auth21

ParâmetroObrigatórioDescrição
request_idsimO mesmo que recebeste no redirect para o teu endpoint bridge.
payloadsimBase64 (UTF-8) do JSON de identidade, sem campo signature dentro do JSON.
signaturesimHex minúsculas: HMAC-SHA256 do valor exacto da string Base64 em payload, com o segredo da consola.

Em Node: crypto.createHmac('sha256', BRIDGE_SECRET).update(payloadB64, 'utf8').digest('hex').

Campos do JSON (antes de Base64)

CampoObrigatórioNotas
timestampsimUnix em segundos; tolerância típica ±300 s face ao servidor Auth21.
emailsimEmail válido.
user_id / subcondicionalIdentificador estável; sub tem prioridade se existir.
tenant, name, picture, apps, roles, permissions, device_idnãoMetadados opcionais repassados nos tokens.

Exemplo de payload

{
  "timestamp": 1712345678,
  "email": "user@empresa.com",
  "user_id": "ext_8821",
  "apps": ["erp", "portal"],
  "roles": ["staff"],
  "permissions": ["read", "write"]
}

Erros frequentes

  • Assinar o JSON em texto claro em vez da string Base64 enviada em payload.
  • timestamp fora da janela permitida.
  • Segredo HMAC diferente entre a consola e o teu servidor.