Autenticação e appserver.ini¶
A API usa OAuth2 (Password Grant). O login é uma conta de serviço do kiosk (não um usuário de negócio): o operador apenas se identifica por matrícula no corpo das requisições.
Como funciona¶
flowchart LR
F["Front (kiosk)"] -- "POST /rest/tlpp/oauth2/token<br/>user + MD5(senha)" --> P[paramsProvider]
P -- "confere MLTEC_0053<br/>HASHBYTES('MD5',SENHA)" --> P
P -- "access_token (JWT)" --> F
F -- "GET/POST apt*** + Bearer" --> V[validaToken]
V -- "ok" --> E[Endpoint]
V -- "inválido" --> X["401"]
paramsProvidervalidaUSUARIO/SENHAcontra aMLTEC_0053(comparaHASHBYTES('MD5', SENHA)com o hash recebido — mesmo esquema doA3_SENHA).validaTokenprotege todos osapt*; só o endpoint de token é público (vianoCheckUri).- Token de acesso expira em 3600 s (1h); o front tem retry único no 401.
Conta de serviço (MLTEC_0053)¶
O DDL cria a conta APONTA com senha placeholder. Defina a senha real (12+ caracteres) e alinhe o front:
-- 1) senha real no banco (texto; será comparada como MD5)
UPDATE dbo.MLTEC_0053 SET SENHA = '<senha real 12+>' WHERE USUARIO = 'APONTA';
// 2) web/config.json — AUTH_PASS = MD5 dessa senha
{
"AUTH_ENABLED": true,
"AUTH_USER": "APONTA",
"AUTH_PASS": "<hash MD5 da senha>"
}
Nunca versione a senha real
A MLTEC_0053 guarda a senha em texto (modelo A3_SENHA, MD5 sem salt) — aceitável em LAN.
Ao expor a API além do proxy/LAN, evolua para hash forte. FILIAL vazio = login compartilhado por
todas as filiais; ATIVO='0' desativa a conta.
appserver.ini — modelo de referência¶
Trecho real do projeto (ajuste caminhos, host, porta e certificado por ambiente). As linhas em destaque são as específicas da solução:
[Drivers]
Active=TCP
MultiProtocolPort=1
[HTTPSERVER]
Enable=1
Servers=HTTP_SSL_SERVER
Compression=1
[HTTP_SSL_SERVER]
hostname=<IP/host do servidor>
port=30019
locations=HTTP_ROOT
Charset=UTF-8
ContentTypes=ContentTypes
SslCertificate=<...>\totvs_certificate.crt
SSLCertificateCA=<...>\totvs_certificate_CA.crt
SslCertificateKey=<...>\totvs_certificate_key.pem
; >>> wiring OAuth2 da solução <<<
tlppdata={"Authorization":{"scheme":"oAuth2","onAuth":"u_validaToken","onAuthNoCheckUri":"u_noCheckUri","onAuthparams":"u_paramsProvider"}}
[HTTP_ROOT]
Path=/rest
RootPath=<...>\protheus_data\web
DefaultPage=index.html
AllowMethods=GET, POST, OPTIONS, DELETE
ThreadPool=THREAD_POOL
CORS=CORS_UPD
[CORS_UPD]
; origem do front (por cliente)
AllowOrigins=https://CLIENTE.mltecnologia.com.br
AllowMethods=GET, POST, OPTIONS, DELETE
[THREAD_POOL]
Environment=environment
UserExits=THREAD_POOL_UEX
MinThreads=2
MaxThreads=4
[THREAD_POOL_UEX]
; abre o ambiente (empresa/filial/módulo PCP) no start do REST
OnStart=u_RESTCONFIGURATIONONSTART
OnStop=u_RESTCONFIGURATIONONSTOP
[ContentTypes]
pdf=application/pdf;charset=UTF-8
json=application/json;charset=UTF-8
; (html, css, js, txt, jpeg…)
Pontos de atenção do .ini
tlppdataliga o OAuth2 aos fontesu_validaToken/u_paramsProvider/u_noCheckUri.OnStart=u_RESTCONFIGURATIONONSTARTabre o ambiente (empresa/filial/módulo) — sem isso os endpoints não têm contexto.CORS AllowOriginsdeve casar com o domínio do front (ex.:https://CLIENTE.mltecnologia.com.br).- HTTPS: PWA exige HTTPS (ou localhost); use o certificado TOTVS (SAN = IP/host) confiável nos terminais — ver Certificado HTTPS (TLS).
noCheckUri¶
Retorna a whitelist de URIs sem token. Hoje volta vazia (as entradas estão comentadas) — o endpoint de token funciona porque o framework REST o isenta. Revalide ao trocar de appserver ou proxy reverso.