auth.oauth
O seu projeto como provedor OAuth 2.1 e OpenID Connect.
Duas coisas diferentes vivem neste namespace, e confundir uma com a outra é a principal fonte de confusão.
Lado consumidor — as aplicações que os seus usuários autorizaram, e que eles podem revisar e desconectar. Uma tela nas suas configurações.
Lado provedor — o seu projeto agindo como issuer, para outras aplicações poderem "entrar com você". Um fluxo inteiro que você hospeda, percorrido em Servidor OAuth — esta página é a referência de métodos dele.
Nenhum dos dois é o auth.authorize(provider),
que manda o seu usuário para o Google. Esse é o sentido oposto: você como
consumidor da identidade de outra pessoa.
grants.list
oauth.grants.list() → OAuthUserGrant[]
As aplicações que o usuário atual autorizou.
const { data: apps } = await nulvless.auth.oauth.grants.list();client{ id, name?, logo_uri?, uri? }RequiredO suficiente para renderizar a aplicação com nome e logo próprios em vez de um id cru.
scopesstring[]RequiredO que esta aplicação recebeu. Mostre — "tem acesso ao seu perfil e e-mail" é o propósito inteiro da tela.
granted_atstringRequiredEles vivem em oauth.grants, não diretamente em oauth.
grants.revoke
oauth.grants.revoke(clientId) → null
Desconecta uma aplicação. Os tokens dela param de funcionar; as outras ficam intocadas.
await nulvless.auth.oauth.grants.revoke(clientId);clientIdstringRequiredVindo do client.id acima.
discovery
discovery() → OAuthDiscovery
O documento de discovery OIDC — o que qualquer client conforme lê para se configurar.
const { data } = await nulvless.auth.oauth.discovery();jwks
jwks() → OAuthJWKS
As chaves públicas contra as quais os seus tokens são verificados.
const { data: keys } = await nulvless.auth.oauth.jwks();Os dois são publicados a partir do momento em que o servidor OAuth é habilitado e ficam em sincronia com as suas configurações. Não há o que regenerar quando você as muda, nem o que hospedar por conta própria.
authorize
authorize(params) → { url }
Inicia o fluxo de authorization code, com PKCE.
await nulvless.auth.oauth.authorize({
client_id,
redirect_uri: 'https://client.example.com/callback',
code_challenge,
code_challenge_method: 'S256',
scope: 'openid profile',
state,
});client_idstringRequiredredirect_uristringRequiredPrecisa estar na lista permitida da aplicação. Verificado antes de qualquer coisa ser emitida.
code_challengestringRequiredPKCE não é opcional aqui.
code_challenge_method'S256'RequiredO único método aceito. plain é recusado.
response_type'code'OptionalscopestringOptionalSeparado por espaços.
statestringOptionalDevolvido de volta ao seu callback. Use, e verifique.
resourcestringOptionalnoncestringOptionalO nonce do OIDC, que amarra um ID token a esta requisição. Não tem relação com o nonce de sudo usado no resto deste SDK.
exchangeCodeForToken
exchangeCodeForToken(params) → OAuthTokenResponse
Troca o authorization code por tokens.
const { data } = await nulvless.auth.oauth.exchangeCodeForToken({
code,
code_verifier,
});codestringRequiredcode_verifierstringRequiredA contraparte PKCE do code_challenge.
redirect_uristringOptionalclient_idstringOptionalclient_secretstringOptionalSó para clients confidenciais. Nunca a partir de um navegador — um client público não tem secret justamente porque não consegue guardar um.
resourcestringOptionalrefreshToken
refreshToken(params) → OAuthTokenResponse
const { data } = await nulvless.auth.oauth.refreshToken({ refresh_token });refresh_tokenstringRequiredclient_idstringOptionalclient_secretstringOptionalgetAuthorization
getAuthorization(authorizationId) → OAuthAuthorization
Carrega uma autorização pendente para você renderizar a tela de consentimento — quem está pedindo, e o quê.
const { data: pending } = await nulvless.auth.oauth.getAuthorization(
authorizationId,
);consent
consent(authorizationId, action) → OAuthConsentResult
Registra a resposta da pessoa.
await nulvless.auth.oauth.consent(authorizationId, 'approve');
await nulvless.auth.oauth.consent(authorizationId, 'deny');authorizationIdstringRequiredactionOAuthConsentActionRequiredapproveEmite o code e continua o fluxo.denyRecusa. O client é redirecionado de volta com um erro.A tela é inteiramente sua — seu nome, seu estilo, seu texto. O que a plataforma
garante é que nada é emitido até o consent mandar, então não há como
conceder acesso por acidente só de renderizar a página.
userinfo
userinfo() → OAuthUserInfo
As claims de UserInfo do OIDC para o access token atual. Chamado pela aplicação client com o token que ela recebeu, não por você.
const { data: claims } = await nulvless.auth.oauth.userinfo();register
register(params) → OAuthApp
Registro dinâmico de client, conforme a RFC 7591 — aplicações se registrando sozinhas em vez de serem criadas por você.
const { data: app } = await nulvless.auth.oauth.register(params);Desligado a menos que você habilite. Com ele desligado, aplicações são criadas
pelo auth.admin.oauthClients, que é o
padrão certo: registro dinâmico permite que qualquer um que alcance o endpoint
crie um client.
O que um terceiro pode pedir
Uma aplicação nunca recebe mais do que a própria pessoa tem. Um token emitido
para um terceiro carrega um subconjunto dos escopos do usuário — então dar
projects:write a uma integração não faz nada se aquela pessoa já não podia
escrever projetos.
Vale dizer isso na sua tela de consentimento. "Este app está pedindo X" é enganoso se a pessoa também não pode fazer X.