Table of Contents
- Modulo de Autenticacao
- Visao geral
- Estrutura de arquivos
- Rotas publicas
- Rotas privadas e perfis
- Fluxo LDAP / Active Directory
- Fluxo Microsoft OAuth
- JWT da aplicacao
- Sessao no frontend
- WebSocket WhatsApp
- Rate limit
- Variaveis de ambiente
- Diagnostico
- Login LDAP falha
- Token invalido ou expirado
- Usuario autenticado cai como unassigned
- Microsoft OAuth falha
- Estado atual
Modulo de Autenticacao
Visao geral
O modulo auth centraliza login, emissao de JWT, validacao de token, autorizacao por perfil e sincronizacao do usuario autenticado com o banco do Omnichannel.
Provedores implementados:
- LDAP / Active Directory: login com usuario e senha corporativos.
- Microsoft OAuth / Entra ID: login via conta Microsoft.
Depois que o provedor confirma a identidade, o backend emite um JWT proprio da aplicacao. Esse token deve ser enviado pelo frontend em todas as rotas privadas usando:
Authorization: Bearer <token>
Estrutura de arquivos
src/modules/auth/
|-- auth.module.ts
|-- auth.controller.ts
|-- auth.service.ts
|-- auth.config.ts
|-- auth-token.service.ts
|-- auth.types.ts
|-- user-access.service.ts
|-- decorators/
| |-- public.decorator.ts
| `-- roles.decorator.ts
|-- dto/
| `-- login.dto.ts
|-- guards/
| |-- jwt-auth.guard.ts
| `-- roles.guard.ts
|-- providers/
| |-- ldap-auth.provider.ts
| |-- microsoft-oauth.provider.ts
| `-- oauth-state.service.ts
`-- repositories/
`-- user-access.repository.ts
Responsabilidades principais:
AuthController: expoe rotas publicas de login e OAuth.AuthService: fachada que delega para LDAP ou Microsoft.AuthTokenService: emite e valida JWT.JwtAuthGuard: exige Bearer token nas rotas privadas.RolesGuard: valida perfis com@Roles().UserAccessService: regra de sincronizacao do usuario autenticado.UserAccessRepository: instrucoes SQL do fluxo de acesso.LoginDto: validacao formal do payload de login.
Rotas publicas
As rotas abaixo nao exigem JWT:
| Metodo | Rota | Descricao |
|---|---|---|
| GET | /health |
Health check da API |
| GET | /auth/config |
Informa provedores de login habilitados |
| POST | /auth/login |
Login LDAP/AD |
| GET | /auth/oauth/microsoft/start |
Inicia login Microsoft |
| GET | /auth/oauth/microsoft/callback |
Recebe callback Microsoft |
Todas as demais rotas HTTP exigem JWT valido.
Rotas privadas e perfis
O JwtAuthGuard foi registrado como guard global. Isso significa que toda rota e privada por padrao, exceto as marcadas com @Public().
Exemplo:
@Public()
@Get('config')
getConfig() {}
Para autorizacao por perfil, o backend usa @Roles():
@Roles('Admin')
@Get('users')
listUsers() {}
Regras atuais:
Admin: acessa administracao, usuarios, areas, base de conhecimento e configuracoes sensiveis.Supervisor: acessa visoes operacionais liberadas para supervisao.Agente: acessa fluxos autenticados sem permissao administrativa.
Fluxo LDAP / Active Directory
Frontend
-> POST /auth/login { username, password }
-> LoginDto valida payload
-> AuthController
-> AuthService.loginWithLdap()
-> LdapAuthProvider.authenticate()
-> valida se LDAP esta habilitado
-> conecta no servidor LDAP
-> faz bind com usuario e senha
-> busca dados do usuario no diretorio, se configurado
-> monta AuthenticatedUser
-> UserAccessService.syncAuthenticatedUser()
-> UserAccessRepository executa SQL
-> cria/atualiza usuarios
-> cria/atualiza usuarios_provedores
-> carrega perfis e areas
-> AuthTokenService.issueToken()
-> retorna { token, user }
O erro retornado ao usuario continua generico (Autenticacao falhou). O erro real e registrado no log interno do provider para diagnostico sem vazar detalhes sensiveis.
Fluxo Microsoft OAuth
Frontend
-> GET /auth/oauth/microsoft/start
Backend
-> gera state assinado com HMAC-SHA256 usando JWT_SECRET
-> redireciona para Microsoft
Usuario
-> autentica na Microsoft
Microsoft
-> chama /auth/oauth/microsoft/callback?code=...&state=...
Backend
-> valida state
-> troca code por access_token
-> consulta Microsoft Graph /me
-> sincroniza usuario no banco
-> emite JWT da aplicacao
-> redireciona para o frontend com payload no fragmento da URL
Frontend
-> le #auth=...
-> salva sessao em sessionStorage
-> limpa a URL
O token nao e mais enviado em query string. Ele vai no fragmento #auth=..., que nao e enviado ao servidor em requisicoes HTTP e e removido pelo frontend apos processamento.
JWT da aplicacao
Payload principal:
{
"sub": "4",
"name": "Nome Completo",
"email": "usuario@empresa.com",
"provider": "ldap",
"username": "usuario",
"perfis": ["Admin"],
"profiles": ["Admin"],
"areas": ["Suporte"],
"areaPrincipal": "Suporte",
"accessStatus": "assigned"
}
O sub usa o ID interno da tabela usuarios.
O token e:
- assinado com
JWT_SECRET; - emitido com expiracao definida por
JWT_EXPIRES_IN; - validado em todas as rotas privadas;
- enviado pelo frontend como Bearer token.
Sessao no frontend
O frontend armazena authToken e authUser em sessionStorage, nao em localStorage.
Motivo:
- reduz persistencia indevida apos fechar o navegador;
- evita reaproveitamento de sessoes antigas salvas localmente;
- continua simples para o modelo atual do produto.
Observacao: uma alternativa ainda mais forte para producao seria cookie HttpOnly + Secure + SameSite, mas exigiria ajuste maior no fluxo do frontend e no CORS.
WebSocket WhatsApp
O namespace Socket.IO /whatsapp tambem exige JWT no handshake.
O frontend envia:
io(WHATSAPP_SOCKET_URL, {
auth: {
token: getAuthToken()
}
});
Sem token valido, o socket nao conecta e nao recebe QR Code, status ou mensagens.
Rate limit
O backend usa @nestjs/throttler com limite global configuravel:
RATE_LIMIT_TTL_MS=60000
RATE_LIMIT_MAX=300
Padrao atual: 300 requisicoes por IP a cada 60 segundos.
Variaveis de ambiente
FRONTEND_URL=http://localhost:3000
JWT_SECRET=uma-chave-longa-e-aleatoria
JWT_EXPIRES_IN=8h
RATE_LIMIT_TTL_MS=60000
RATE_LIMIT_MAX=300
AUTH_PROVIDERS=ldap,microsoft
LDAP_ENABLED=true
LDAP_URL=ldaps://servidor-ad:636
LDAP_DOMAIN=empresa.com.br
LDAP_USER_DN_TEMPLATE={{username}}@empresa.com.br
LDAP_SEARCH_BASE=DC=empresa,DC=com
LDAP_SEARCH_FILTER=(&(objectClass=user)(sAMAccountName={{username}}))
LDAP_TIMEOUT_MS=5000
MICROSOFT_ENABLED=false
MICROSOFT_TENANT_ID=common
MICROSOFT_CLIENT_ID=
MICROSOFT_CLIENT_SECRET=
MICROSOFT_REDIRECT_URI=http://localhost:3001/auth/oauth/microsoft/callback
MICROSOFT_SUCCESS_REDIRECT_URL=http://localhost:3000/login
JWT_SECRET deve ser forte e exclusivo por ambiente.
Diagnostico
Login LDAP falha
- Verifique
LDAP_URL,LDAP_DOMAINeLDAP_USER_DN_TEMPLATE. - Confirme conectividade do backend com o AD.
- Verifique se
LDAP_SEARCH_BASEeLDAP_SEARCH_FILTERbatem com o diretorio. - Consulte logs do backend; o provider registra o motivo interno sem expor para o usuario.
Token invalido ou expirado
- Verifique se o frontend esta enviando
Authorization: Bearer <token>. - Verifique se
JWT_SECRETnao mudou depois da emissao do token. - Faca login novamente para renovar a sessao.
Usuario autenticado cai como unassigned
- O login funcionou, mas faltam perfil/area no banco.
- Um Admin deve atribuir perfil e area para o usuario.
Microsoft OAuth falha
- Verifique
MICROSOFT_REDIRECT_URIno Azure e no.env. - Confirme
MICROSOFT_CLIENT_IDeMICROSOFT_CLIENT_SECRET. - Refaca o fluxo se o state expirar.
Estado atual
- Login LDAP/AD
- Login Microsoft OAuth
- State OAuth assinado
- JWT emitido pela aplicacao
- JWT validado nas rotas privadas
- Roles no backend
- Bearer token no frontend
- Token fora de query string no OAuth
- WebSocket WhatsApp protegido por token
- SQL de acesso isolado em repository
- DTO e ValidationPipe no login
- Rate limit global
- Auditoria formal de login em tabela propria
- Cookie HttpOnly como alternativa futura ao sessionStorage