Documentação
Servidor OAuthInício rápido

Início rápido

Ligue o Servidor OAuth, registre um cliente e complete uma autorização de ponta a ponta.

Quinze minutos, e no fim um app de terceiro tem um token emitido pelo seu projeto.

Ligue o servidor

No Console, abra Servidor OAuth no ambiente em que você está trabalhando.

Três configurações decidem como o fluxo se comporta:

Habilitadodesligado por padrãoOptional

Enquanto estiver desligado, /oauth/authorize responde 403. Nada mais no seu projeto é afetado.

URL da tela de consentimentopadrão: seu Site URLOptional

Onde a sua tela de consentimento está hospedada, se não for no seu Site URL. Deixe vazio e o Site URL é usado — o mesmo que carrega links de confirmação e e-mail de boas-vindas.

Caminho de autorização/oauth/consentOptional

O caminho da tela de consentimento, anexado à URL acima.

O Console mostra a URL de consentimento resultante abaixo do campo. Se ela não parecer uma página do seu app, o Site URL está errado.

Registre um cliente

Ainda em Servidor OAuth, adicione uma aplicação. Você precisa de um nome que o usuário reconheça na tela de consentimento e ao menos um redirect URI.

Nome          Acme Analytics
Redirect URI  https://acme.example.com/callback

Redirect URIs casam exatamente — esquema, host, porta e caminho. https://acme.example.com/callback não casa com https://acme.example.com/callback/ nem com …/callback?x=1. É exigência do OAuth 2.1, e é o que impede um atacante de redirecionar os códigos dos seus usuários para outro lugar.

Você recebe um client_id, e um client_secret se o app puder guardar um. O segredo é mostrado uma única vez.

Construa a tela de consentimento

O cliente vai mandar os usuários para o seu Caminho de autorização. Essa página precisa existir antes do fluxo poder terminar — é onde o usuário vê o que está sendo pedido e diz sim.

São três chamadas: ler o pedido, renderizar e registrar a resposta.

const { data } = await nulvless.auth.oauth.getAuthorization(authorizationId);
// data.client.name, data.client.logoUri, data.scope, data.autoApproved

const { data: result } = await nulvless.auth.oauth.consent(authorizationId, 'approve');
redirect(result.redirect.uri);

Construindo a tela de consentimento traz isso em Next.js, Nuxt, SvelteKit e Remix, com as partes fáceis de errar.

Mande um usuário pelo fluxo

Do lado do cliente, com PKCE:

const verifier = crypto.randomUUID() + crypto.randomUUID();
const challenge = base64url(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier)));

const url = new URL(`${issuer}/oauth/authorize`);
url.searchParams.set('client_id', clientId);
url.searchParams.set('redirect_uri', 'https://acme.example.com/callback');
url.searchParams.set('response_type', 'code');
url.searchParams.set('scope', 'openid email');
url.searchParams.set('state', state);
url.searchParams.set('code_challenge', challenge);
url.searchParams.set('code_challenge_method', 'S256');

location.assign(url.toString());

Guarde verifier e state onde o callback consiga ler. O verifier é a prova de que o app que termina o fluxo é o mesmo que o começou.

Troque o código

O usuário aprova, e sua tela de consentimento o devolve ao redirect URI com ?code=…&state=…. Confira que o state bate e troque o código:

const response = await fetch(`${issuer}/oauth/token`, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code,
    redirect_uri: 'https://acme.example.com/callback',
    code_verifier: verifier,
    client_id: clientId,
    client_secret: clientSecret, // só clientes confidenciais
  }),
});

const { access_token, refresh_token, id_token, expires_in } = await response.json();

id_token só vem se você pediu o escopo openid. É ele que diz quem entrou.

Confirme que funcionou

Chame o endpoint de userinfo com o access token:

curl https://seu-projeto.nulvless.co/auth/oauth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Você deve receber as claims cobertas pelos escopos que pediu. Se vier 401, o token expirou ou foi emitido por outro ambiente.

Não pule o state

O state é o que impede um terceiro de induzir um usuário logado a completar a autorização de outra pessoa. Custa uma comparação no seu callback. O fluxo funciona sem ele, até o dia em que não funciona.

Próximo

Nesta página