Documentação
ReferênciaSDK JavaScriptSessionManager

SessionManager

O ciclo de vida do token que o client de navegador roda por você, e como conduzi-lo direto.

O client de navegador mantém uma sessão viva sem você fazer nada: ele guarda os tokens, percebe quando o access token está perto de expirar, troca o refresh token por um par novo, e levanta um evento quando não consegue.

Você nunca chama isso diretamente — o client de navegador é dono dele. O auth.getAccessToken() e o auth.refreshSession() são as portas públicas e os dois passam por aqui. Esta página é para quando você precisa saber o que acontece por baixo.

Só no navegador. O createServerClient não tem session manager, porque um servidor não guarda a sessão de um usuário específico para manter viva.

O que fica guardado

access_tokenstringRequired

O que vai na requisição.

refresh_tokenstringOptional

O que compra o próximo. Sem ele uma sessão não sobrevive ao vencimento.

expires_atnumberRequired

Um timestamp epoch absoluto, calculado na gravação como now + expires_in. O padrão é uma hora quando o servidor não informa.

userUserOptional

Carregado para o client conseguir responder "quem está autenticado" sem requisição.

Repare que ele guarda um vencimento absoluto, não o expires_in relativo que o servidor devolve. Uma sessão guardada continua correta depois de a aba ficar uma hora dormindo, o que não aconteceria com uma contagem regressiva.

getValidToken

getValidToken() → string | null

Devolve um token utilizável, renovando antes se ele estiver perto de expirar.

const token = await nulvless.auth.getAccessToken(); // passa por aqui

A regra é uma margem de 90 segundos: se o token expira em menos que isso, ele é renovado antes de ser entregue. Essa margem existe para um token nunca ser entregue e depois rejeitado no meio do caminho — a requisição teria falhado entre a sua checagem e a do servidor.

Devolve null em três casos, e vale distingui-los:

sem sessãonull

Nada guardado. Ninguém autenticado.

sem refresh tokennull

Existe sessão, mas ela não consegue se renovar. Levanta unauthorized.

renovação recusadanull

O servidor recusou o refresh token — um 401, ou um token desconhecido, já usado, emitido em outro lugar ou de um usuário banido. A sessão guardada é apagada e unauthorized é levantado.

Uma renovação que apenas não conseguiu terminar — sem rede, timeout, 429, 5xx — é tentada de novo até três vezes, com backoff. Se ainda falhar, volta null, mas a sessão é mantida, então uma conexão instável nunca desautentica ninguém.

É por isso que segurar a string do token anula o mecanismo. Peça a cada requisição:

await fetch('/api/projects', {
  headers: { Authorization: `Bearer ${await nulvless.auth.getAccessToken()}` },
});

refreshSession

auth.refreshSession() → string | null

Renova o access token agora, independente de quanta vida ele ainda tenha, e compartilha a tentativa com qualquer renovação já em andamento. Devolve o token novo, ou null quando a sessão não pôde ser recuperada.

const token = await nulvless.auth.refreshSession();

Use depois que algo mudou no servidor e o token atual ainda não carrega — scopes novos depois de aceitar um convite, por exemplo.

forceRefresh

forceRefresh({ deauthOnFailure }) → string | null

O que o refreshSession chama, e o que o próprio client chama depois de um 401 ou de um 403 forbidden_resource_access. Renova independente de quanta vida o token atual ainda tenha — a não ser que outra aba já o tenha substituído, caso em que esse token é devolvido sem uma segunda troca.

deauthOnFailurebooleanOptionaldefault true

O que acontece quando a própria renovação falha.

true

Apaga a sessão guardada e levanta unauthorized. É o comportamento certo depois de um 401 — a sessão realmente acabou.

false

Deixa a sessão intacta e apenas devolve null. Para uma renovação suave, quando a falha original era sobre permissão e não sobre identidade.

A distinção importa. Um 403 forbidden_resource_access significa que a pessoa está autenticada e não tem permissão — desautenticá-la ali seria derrubar alguém por ter clicado no botão errado. Passe deauthOnFailure: false para quem chamou conseguir mostrar o erro real.

Renovação agendada

Com autoRefresh ligado (o padrão), o client de navegador não espera uma requisição encontrar o token vencido. A cada 30 segundos — e assim que uma aba oculta volta a ficar visível — ele confere a sessão guardada e a renova quando ela entra na margem de 90 segundos.

  • Abas ocultas pulam a conferência. Uma aba em segundo plano não mantém aquecida uma sessão que ninguém está olhando.
  • Uma aba renova por vez. Abas do mesmo projeto se coordenam pela Web Locks API onde ela existe; uma aba que encontra o lock ocupado pula aquele ciclo.
  • Toda aba fica sabendo. O token novo é transmitido por BroadcastChannel, e cada aba emite token-refreshed.

Desligue com createClient(url, key, { autoRefresh: false }) quando o host controla a renovação. A renovação no uso continua acontecendo.

Chame auth.dispose() quando descartar um client — testes, hot reload, um micro-frontend sendo desmontado. Ele para o timer e fecha o canal entre abas.

Callbacks

Três hooks conduzem tudo acima. O client de navegador liga eles aos eventos que você assina, então assinar normalmente basta.

setRefreshFn(refresh_token) => Promise<Result>Optional

Como trocar um refresh token. Definido pelo client na construção — é injetado depois em vez de passado, para evitar uma dependência circular entre o manager e o client HTTP.

setOnTokenRefreshed(auth) => voidOptional

Dispara depois de cada renovação bem-sucedida. Vira o evento token-refreshed.

setOnUnauthorized(failed) => voidOptional

Dispara quando a sessão não consegue ser renovada. Vira o evento unauthorized, e carrega a sessão que falhou para uma aplicação multi-conta remover a entrada certa.

save, get, clear

save(auth) · get() · clear()

As primitivas de armazenamento. O save calcula o expires_at e escreve pelo adaptador de storage configurado; o clear remove a sessão ativa e nada mais — o armazenamento de contas fica intacto, e é isso que permite ao deselect largar uma sessão e ainda voltar para ela.

O signOut chama o clear por você, e só depois que o servidor confirma — então um logout que falha não deixa o client desautenticado localmente e vivo remotamente.

Próximos

Nesta página