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)
| Modo | Onde está a password do utilizador | O que escolhes na consola |
|---|---|---|
| Hosted | Na Auth21 | O utilizador faz login nos ecrãs da Auth21 (registo / login na tua org). |
| Bridge | No teu sistema | Indicas 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. |
| Enterprise | Reservado | Fluxo 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_idereturn_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.comou 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óvel —
ISSUER/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 link —
ISSUER/mobile-handoff-qr?token=ID(podes mostrar no desktop; o utilizador escaneia com a câmara). - Iframe compacto —
ISSUER/mobile-handoff-qr?token=ID&embed=1para 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:
- O utilizador inicia o login OAuth na Auth21.
- A Auth21 redirecciona o browser para o teu Endpoint bridge com
request_idereturn_to(URL do serviço Auth21 onde deves enviar o resultado). Para o utilizador continuar no telemóvel sem criares página própria, usaISSUER/mobile-handoff?token=+ o mesmorequest_id(ver secção Hosted — Telemóvel). - No teu site, autenticas o utilizador como já fazes hoje.
- 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. - Redireccionas o browser para
return_tocomrequest_id,payloadesignature(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âmetro | Obrigatório | Descrição |
|---|---|---|
request_id | sim | O mesmo que recebeste no redirect para o teu endpoint bridge. |
payload | sim | Base64 (UTF-8) do JSON de identidade, sem campo signature dentro do JSON. |
signature | sim | Hex 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)
| Campo | Obrigatório | Notas |
|---|---|---|
timestamp | sim | Unix em segundos; tolerância típica ±300 s face ao servidor Auth21. |
email | sim | Email válido. |
user_id / sub | condicional | Identificador estável; sub tem prioridade se existir. |
tenant, name, picture, apps, roles, permissions, device_id | não | Metadados 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. timestampfora da janela permitida.- Segredo HMAC diferente entre a consola e o teu servidor.