OAuth 2.1 para aplicativos
Authorization code com PKCE, refresh tokens rotativos, scopes e os endpoints que um aplicativo chama.
API keys cobrem integrações servidor a servidor. OAuth é para um aplicativo que age em nome de um membro, com o consentimento desse membro: um aplicativo mobile, ou uma ferramenta de terceiros que um membro conecta à conta dele.
Flows#
- Authorization code com PKCE (S256), obrigatório para todo client. Clients públicos, como aplicativos mobile, não guardam segredo; clients confidenciais podem ter um.
- Refresh tokens rotacionam. Cada uso emite um novo e invalida o anterior. Reusar um refresh token rotacionado revoga a família inteira, e é assim que um token roubado é detectado.
- Sem implicit flow, sem password grant. Device authorization não está na v1.
Endpoints#
| Endpoint | O que faz |
|---|---|
GET /oauth/authorize |
A tela de consentimento, na sessão do membro, listando os scopes em linguagem simples |
POST /oauth/token |
Grants authorization_code e refresh_token |
POST /oauth/revoke |
Revoga um token |
GET /oauth/userinfo |
Perfil mínimo, conforme os scopes concedidos |
GET /.well-known/oauth-authorization-server |
Metadados, RFC 8414 |
Tempo de vida dos tokens#
| Artefato | Tempo de vida | Notas |
|---|---|---|
| Authorization code | 60 segundos | Uso único |
| Access token | 1 hora | Opaco, não é um JWT; armazenado como hash SHA-256 |
| Refresh token | 30 dias | Rotativo |
Access tokens são opacos de propósito. Um JWT que não pode ser revogado antes de expirar é a troca errada para um aplicativo que um membro pode desconectar a qualquer momento.
Redirect URIs#
Registradas por client e comparadas de forma exata. Esquemas personalizados
(bondry-app://callback) e loopback (http://127.0.0.1:<port>) são
permitidos para aplicativos nativos; localhost só é aceito em ambiente
local.
Scopes#
Os mesmos scopes das API keys, declarados pelo core e por cada módulo:
members.read, community.write, blog.read, messages.*,
notifications.*, account.*, além de profile para identidade mínima e
offline_access para um refresh token.
O gate aceita um bearer token do OAuth ou de uma API key. Um token do OAuth carrega o membro, então as permissões de grupo do membro se aplicam em cima do scope.
Aviso Um scope nunca amplia o que o membro não pode fazer. Solicitar
community.writepara um membro que não pode postar continua falhando.
Registrando um client#
System > API > OAuth clients no painel: nome, logo, site, redirect URIs, e se o client é confidencial. O segredo de um client confidencial é mostrado uma única vez. Toda alteração é gravada no log de administração.
O que o membro vê#
- A tela de consentimento, renderizada no tema do site, com o nome e o logo do aplicativo, os scopes explicados, um aviso explícito quando o aplicativo não é first-party, e os botões Permitir e Negar.
- Account > Connected apps, listando todo aplicativo autorizado com seus scopes e o último uso, e um botão que revoga o aplicativo e toda a família de tokens dele.
A revogação se propaga em cascata: banir ou excluir um membro, ou revogar o client, revoga os tokens.
Notas de implementação#
stateé obrigatório e é devolvido de volta.- PKCE é obrigatório, com S256.
- Comparações de hash são em tempo constante.
/oauth/tokentem rate limit por client e por IP.- Tokens nunca aparecem em log.
Todo flow e toda recusa tem um teste: verificador de PKCE errado, redirect URI diferente, code reutilizado, refresh token rotacionado reutilizado, scope não concedido, membro banido.