Pular para o conteúdo principal

Autenticação

A LightHouse API usa JWT Bearer para autenticar requisições. Os tokens são emitidos pelo AuthCenter — o provedor de identidade central do Leankeep — e validados pela API a cada chamada.

Visão geral do fluxo

┌──────────┐ 1. credenciais ┌──────────────┐
│ Cliente │ ──────────────────► │ AuthCenter │
│ │ ◄────────────────── │ (identidade)│
└──────────┘ 2. JWT (access) └──────────────┘

│ 3. Authorization: Bearer <JWT>

┌──────────────────┐ 4. valida assinatura via JWKS
│ LightHouse API │ ──────────────────────────────► AuthCenter /jwks
│ │ ◄────────────────────────────── chaves públicas
└──────────────────┘ 5. extrai claims (empresa, usuário) e responde
  1. O cliente autentica no AuthCenter e recebe um access_token (JWT).
  2. O cliente envia o token em toda requisição à LightHouse API.
  3. A API valida a assinatura do token usando as chaves públicas do JWKS do AuthCenter.
  4. A API extrai os claims de contexto (empresa, usuário) e aplica as regras de autorização.

Ambientes

AmbienteAuthCenter (emissão de token)LightHouse API (dados)
Produçãohttps://auth.lkp.app.brhttps://lighthousev2.lkp.app.br
Sandboxhttps://auth.lkp.dev.brhttps://lighthouse.lkp.dev.br

Obtendo o token (AuthCenter)

O token é emitido pelo AuthCenter via POST com corpo multipart/form-data.

AmbienteEndpoint
ProduçãoPOST https://auth.lkp.app.br/v1/auth/
SandboxPOST https://auth.lkp.dev.br/v1/auth/

Campos do formulário

CampoTipoDescrição
loginstringUsuário (e-mail ou login configurado)
PasswordstringSenha
PlataformintOrigem da requisição. Mesmo enum EPlataforma usado no campo plataforma dos corpos da LightHouse API (ver Glossário → plataforma) — testado: 6 (API) funciona em ambos. Para integrações via API, use 6.
ExpireCurrentSessionboolTrue encerra sessão ativa anterior
StayConnectedboolTrue mantém sessão prolongada

Exemplo cURL — produção

curl --location 'https://auth.lkp.app.br/v1/auth/' \
--form 'login=SEU_USUARIO' \
--form 'Password=SUA_SENHA' \
--form 'Plataform=6' \
--form 'ExpireCurrentSession=True' \
--form 'StayConnected=True'
Não coloque aspas dentro do valor

curl --form campo=valor já delimita o valor pela sintaxe do próprio --form. Escrever --form 'login="SEU_USUARIO"' (aspas duplas dentro das aspas simples) envia as aspas como parte literal do valor — testado: o AuthCenter espera o valor sem aspas internas.

Exemplo cURL — sandbox

curl --location 'https://auth.lkp.dev.br/v1/auth/' \
--form 'login=SEU_USUARIO' \
--form 'Password=SUA_SENHA' \
--form 'Plataform=6' \
--form 'ExpireCurrentSession=True' \
--form 'StayConnected=False'

Resposta

{
"success": true,
"message": null,
"hasActiveSession": false,
"authToken": {
"jti": "c1d5914709eb4ca19e67dd71e417ed20",
"token": "<JWT>",
"refreshToken": "<refresh>",
"expiresIn": "2026-07-01T20:40:14.449893Z",
"refreshExpiresIn": "2026-07-08T18:40:14.4551852Z"
}
}
CampoDescrição
successtrue se a autenticação foi bem-sucedida.
messageMensagem de erro/aviso, quando houver (null em caso de sucesso).
hasActiveSessiontrue se já havia uma sessão ativa para o usuário (ver ExpireCurrentSession acima).
authToken.jtiID único do token (JWT ID) — útil para rastreio/revogação.
authToken.tokenO JWT a ser usado nas chamadas. Vai em Authorization: Bearer <authToken.token>.
authToken.expiresInData/hora (UTC) de expiração do token. Vale por ~2 horas a partir da emissão.
authToken.refreshTokenToken de renovação — usado apenas no endpoint de refresh (abaixo), nunca na LightHouse API.
authToken.refreshExpiresInData/hora (UTC) de expiração do refreshToken. Vale por ~7 dias.
O JWT está aninhado

O token não vem no topo da resposta — está em authToken.token. Um erro comum é tentar usar response.token diretamente; o campo correto é response.authToken.token.

Renovando o token (refresh)

Antes que o token expire (authToken.expiresIn, ~2h), renove-o usando o authToken.refreshToken — sem precisar reautenticar com usuário e senha.

AmbienteEndpoint
ProduçãoPOST https://auth.lkp.app.br/v1/auth/refresh
SandboxPOST https://auth.lkp.dev.br/v1/auth/refresh
Formato diferente do login

O login (POST /v1/auth/) usa multipart/form-data. O refresh usa application/x-www-form-urlencoded — é intencional, não confunda os dois formatos. Enviar o refresh como multipart (ou o login como urlencoded) resulta em erro de parsing no AuthCenter.

Campos do formulário

CampoTipoDescrição
TokenstringO JWT atual (authToken.token), mesmo que já esteja perto de expirar.
RefreshTokenstringO authToken.refreshToken recebido no login (ou no refresh anterior).

Exemplo cURL

curl --location 'https://auth.lkp.app.br/v1/auth/refresh' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'Token=SEU_JWT' \
--data-urlencode 'RefreshToken=SEU_REFRESH_TOKEN'

A resposta tem a mesma estrutura do login — success, authToken.token, authToken.refreshToken, authToken.expiresIn, authToken.refreshExpiresIn — só que com a expiração renovada. Substitua o token e o refresh token armazenados pelos novos valores retornados.

Padrão de uso recomendado

  1. Autentique uma vez (POST /v1/auth/) e guarde authToken.token e authToken.refreshToken.
  2. Use authToken.token em todas as chamadas até perto de authToken.expiresIn.
  3. Antes de expirar (~2h), chame POST /v1/auth/refresh com o Token e RefreshToken atuais.
  4. Substitua os valores armazenados pelos novos authToken.token/authToken.refreshToken da resposta.
  5. Se o refreshToken também expirar (~7 dias sem uso), reautentique com usuário e senha — não há como renovar depois desse prazo.

Enviando o token

Inclua o header em todas as chamadas, usando o valor de authToken.token obtido no login (ou no refresh):

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6...
curl "https://lighthousev2.lkp.app.br/v1/empresas/ativas" \
-H "Authorization: Bearer SEU_TOKEN"

Contexto de empresa

Não existe um padrão único: dependendo do endpoint, a API espera o empresaId de uma forma diferente. Confira sempre os parâmetros do endpoint específico na Referência de API antes de montar a chamada — nunca assuma o padrão por analogia com outro endpoint.

Tabela canônica — contexto de empresa por endpoint

PadrãoOnde vai o empresaIdEndpoints (exemplos)
Header HTTP obrigatórioEmpresaId como header — não é query paramGET /v1|v2|v3/ocorrencias, GET /v1|v3/ocorrencias/count, os 4 GET /v1/reports/*
Header HTTP (kit de discovery, validado 07/2026)EmpresaId como header — não é query paramGET /v1/unidades/ativas, GET /v1/sistemas, GET /v1/areas, GET /v1/equipamentos, GET /v1/usuarios — ver Primeiros passos → Descobrindo seu EmpresaId
Path param{empresaId} na própria URLGET /v3/ocorrencias/config/{empresaId}, GET /v3/ocorrencias/tipicas/{empresaId}
Campo obrigatório no corpoempresaId no JSON do POST/PUTPOST /v3/ocorrencias (SaveOcorrenciaCommand)
⚠️ Indefinidospec declara EmpresaId como query param opcional, mas o comportamento real não foi confirmado — um 500 de sintaxe nesse endpoint mascarou o teste isolado (ver Dar baixa em lote → Passo 1)GET /v1/atividades

Fora esses padrões, não existe um formato de EmpresaId como query param nos endpoints de ocorrências — se você ver esse formato em algum exemplo desta documentação, é erro do exemplo, não um padrão válido da API. Para /v1/atividades, o formato indefinido acima é a exceção conhecida.

As regras de autorização dependem do escopo resolvido: um usuário só enxerga dados das empresas a que tem acesso. Veja a matriz de acesso por tipo de usuário em Conceitos de domínio.

Endpoints sem autenticação

Poucos endpoints dispensam token:

EndpointUso
GET /v{N}/qrcode/publicLeitura de QR Code público (área/equipamento sem login).

Todos os demais exigem Authorization: Bearer.

Erros de autenticação

CódigoSignificadoAção
401 UnauthorizedToken ausente, expirado ou assinatura inválida.Reautentique no AuthCenter e obtenha um novo token.
403 ForbiddenAutenticado, mas sem permissão para o recurso/empresa.Verifique o escopo do usuário.

Boas práticas

  • Cache do token respeitando a expiração; não reautentique a cada chamada.
  • Renove com antecedência — chame o refresh antes de authToken.expiresIn (~2h) para evitar 401 no meio de uma operação.
  • Relógio sincronizado — claims de expiração são sensíveis a clock skew.
  • Nunca exponha o token, o refresh token ou o jti em logs, URLs ou no front-end público.