Quem entrou, no código
A cada requisição, a plataforma entrega à aplicação a identidade de quem entrou, assinada. O SDK de TypeScript a confere e devolve a pessoa; em outra linguagem, a conferência é a mesma e está no protocolo de runtime.
Instalar
Baixe o pacote de TypeScript em zero.nnumbers.com.br/downloads e instale o arquivo:
npm install ./zero-sdk-typescript.tgz
No servidor: @nnumbers/zero/app
import { NNumbers, UnauthenticatedError } from '@nnumbers/zero/app'
const nn = NNumbers.init() // lê as variáveis NNUMBERS_*
app.get('/api/me', async (req, res) => {
res.json({ user: await nn.auth.user(req) }) // a pessoa, ou null
})
app.get('/painel', async (req, res) => {
try {
const user = await nn.auth.requireUser(req, req.url)
res.send(`Olá, ${user.name ?? user.username}`)
} catch (e) {
if (e instanceof UnauthenticatedError) return res.redirect(e.loginPath)
throw e
}
})
| API | O que faz |
|---|---|
NNumbers.init() | o contexto da aplicação: appId, org e auth |
nn.auth.user(req) | quem entrou, ou null |
nn.auth.requireUser(req, returnTo) | como user, mas sem pessoa lança UnauthenticatedError com o loginPath que volta a returnTo |
nn.auth.loginPath(returnTo) | o caminho do login; destino fora da aplicação vira / |
nn.auth.logoutPath | o caminho da saída (POST, a partir de um formulário da própria aplicação) |
nn.auth.sessionPath | o estado da sessão, para o navegador |
user aceita a requisição do Node, a Request do fetch ou um objeto de cabeçalhos. Há um exemplo completo, sem framework, em examples/organization-iam no repositório do SDK.
| Erro | Código | Quando |
|---|---|---|
AppConfigurationError | ORGANIZATION_IAM_NOT_ENABLED | a aplicação roda sem a capacidade ligada, ou fora do Zero |
UnauthenticatedError | USER_SESSION_REQUIRED | a rota exige alguém e ninguém entrou |
IdentityAssertionError | IDENTITY_ASSERTION_INVALID | chegou uma identidade que não confere — nunca vira pessoa |
Na interface: @nnumbers/zero/react
Componentes e hooks para React 18 ou 19 (react é dependência opcional). Eles leem a sessão que a plataforma guarda e levam aos caminhos reservados; nenhum vê token. A interface mostra quem entrou — quem decide é o servidor, com nn.auth.user(req).
import { NNumbersProvider, Authenticated, Unauthenticated, LoginButton, UserMenu, useUser, useOrganization } from '@nnumbers/zero/react'
export function App() {
return (
<NNumbersProvider>
<header><UserMenu /></header>
<Authenticated fallback={<LoginButton>Entrar com a organização</LoginButton>}>
<Painel />
</Authenticated>
<Unauthenticated>
<p>Entre com a conta da organização.</p>
</Unauthenticated>
</NNumbersProvider>
)
}
function Painel() {
const user = useUser() // SessionUser | null | undefined (carregando)
const org = useOrganization() // { id, slug }
return <p>Olá, {user?.name} — {org?.slug}</p>
}
| API | O que faz |
|---|---|
<NNumbersProvider> | lê a sessão uma vez e a entrega abaixo; initialSession evita a busca (renderização no servidor, testes) |
useAuth() | { user, organization, loading, error, refresh(), loginPath(returnTo?), logoutPath } |
useUser() | quem entrou; null se ninguém; undefined enquanto carrega |
useOrganization() | a organização dona da aplicação |
<Authenticated fallback?> | o conteúdo para quem entrou, o fallback para quem não entrou, nada enquanto carrega |
<Unauthenticated> | o conteúdo para quem NÃO entrou; nada para quem entrou, nem enquanto carrega |
<LoginButton returnTo?> | link para o login da organização, voltando à página atual (ou a returnTo) |
<LogoutButton> | formulário POST para a saída |
<UserMenu> | o nome de quem entrou e a saída |
readSession() | a mesma leitura, sem React |
Em outra linguagem
A identidade chega no cabeçalho X-NNumbers-Identity: um JWS compacto, algoritmo ES256, typ nn-identity+jwt. Confira sempre, em toda requisição — um cabeçalho sem assinatura conferida não prova nada:
- A assinatura, com as chaves públicas do endereço em
NNUMBERS_IDENTITY_JWKS. Guarde as chaves por alguns minutos e busque de novo quando chegar umkiddesconhecido. issigual aNNUMBERS_IDENTITY_ISSUER.audigual aNNUMBERS_APP_ID— a identidade entregue a outra aplicação não vale aqui.orgigual aNNUMBERS_ORG_ID.nbfeexp: a identidade vale por 5 minutos, com até 60 s de tolerância de relógio.
Sem o cabeçalho, a requisição é anônima. Com o cabeçalho e qualquer conferência falhando, recuse — nunca trate como pessoa.
| Claim | O que é |
|---|---|
sub | o identificador da pessoa no IAM da organização |
org, org_slug | a organização |
iam | o endereço do IAM da organização |
sid | a referência da sessão |
name, email, email_verified, preferred_username | quando a conta os tem |
iat, nbf, exp, jti | o prazo e o identificador desta identidade |
O protocolo de runtime descreve os caminhos reservados, o broker e a consulta ao QueryMesh em outra linguagem.
As variáveis da plataforma
Com a capacidade ligada, a publicação injeta:
| Variável | O que é |
|---|---|
NNUMBERS_APP_ID | o id desta aplicação (svc_…) |
NNUMBERS_ORG_ID, NNUMBERS_ORG_SLUG | a organização do projeto |
NNUMBERS_IDENTITY_ISSUER | o emissor da identidade |
NNUMBERS_IDENTITY_JWKS | o endereço das chaves públicas — alcançável só de dentro da plataforma |
NNUMBERS_BROKER_URL | o endereço do broker, onde a aplicação consulta o QueryMesh em nome de quem entrou — alcançável só de dentro da plataforma |
O prefixo NNUMBERS_ é da plataforma: a configuração do serviço não aceita variável com ele.
Próximos passos
Esta página ajudou?
Reportar um problema nesta páginaNão envie senhas, chaves, tokens ou dados de clientes.