Login por biometria
O login por biometria permite abrir o app e entrar sem digitar senha nem código — a impressão digital ou o rosto destravam o acesso. É seguro por desenho: a sua senha nunca fica guardada no aparelho, e a credencial usada é rotativa, vinculada ao aparelho e revogável.
Como funciona por baixo (Opção B)
Ao ativar a biometria, o app recebe um token de renovação de biometria (rotativo, 256 bits) e o guarda no cofre do aparelho (Keychain no iOS / Keystore no Android), protegido pela sua biometria. Na próxima vez, a biometria destrava esse token e ele é trocado por uma sessão nova. O servidor guarda apenas um hash do token — nunca o token em si.
Ativar o login por biometria
- Faça login normalmente (e-mail + senha e, se aplicável, o código de verificação).
- Vá em Configurações → Segurança e ligue Ativar login por biometria.
- Confirme com a sua biometria. Pronto — o aparelho passa a ser um device confiável.
O aparelho ativado aparece na tela de Gerenciamento de dispositivos.
Entrar com biometria
- Abra o app. Na tela de acesso, toque em Entrar com biometria (ou é oferecido automaticamente).
- Autentique-se com digital/rosto. Você cai direto na sua tela inicial.
Desativar / revogar
- Em Configurações → Segurança, desligue Ativar login por biometria; ou
- Em Gerenciamento de dispositivos, remova o aparelho — isso revoga a biometria daquele device.
- Ao sair (logout), a biometria daquele aparelho também é revogada.
Segurança
- A credencial expira em ~90 dias — depois disso é preciso um login completo (senha + código) para reativar.
- Operações sensíveis (transferências, saques) continuam pedindo verificação adicional (step-up). A biometria destrava a sessão, não as ações críticas.
- Se a biometria do aparelho for alterada, o cofre invalida a credencial automaticamente.
Referência técnica (endpoints)
Feature interna do Midas-Web. Estende a tabela users_devices (o token de biometria é 1:1 com o device confiável). Base de confiança = device_uid (Device.getId(), único por instalação).
POST /v1/authentication/biometric/enroll — ativar (autenticado)
Requer sessão válida (@AuthenticationRequired). userId vem da sessão.
Request body:
{ "deviceUid": "<Device.getId().identifier>", "deviceName": "iPhone do Tony" }Header opcional device: JSON de telemetria do aparelho (model, os, platform, manufacturer, isNative, deviceType).
Response 200:
{ "biometricRefreshToken": "<version>.<secretHex>", "expiresAt": "2026-10-15T12:00:00.000Z" }O biometricRefreshToken é retornado uma única vez, em texto claro. Guardar no Keychain/Keystore. Erros: 400 (falta deviceUid), 412 (falha ao ativar).
POST /v1/authentication/biometric/refresh — login por biometria (público)
Público (sem sessão), com rate limit por IP e por device. Troca o token por uma sessão nova e seta os cookies JWT httpOnly (o mesmo caminho do authenticateuser), sem senha nem OTP.
Request body:
{ "deviceUid": "<...>", "biometricRefreshToken": "<...>", "applicationName": "MIDAS_WEB" }Response 200: os dados do usuário (mesmo shape do authenticateuser, sem os campos jwt*) mais o token rotacionado:
{
"id": "…", "email": "…", "name": "…", "status": "APPROVED", "bankingAccount": { "…": "…" },
"biometricRefreshToken": "<novo version>.<novo secretHex>",
"biometricTokenExpiresAt": "2026-10-15T12:00:00.000Z"
}Cookies setados: o cookie de sessão httpOnly (mesma sessão do login por senha).
O frontend deve substituir o token guardado no Keychain pelo biometricRefreshToken retornado (rotação). Erros: 400 (falta campo), 403 (user-agent não-browser / usuário bloqueado), 412 (token inválido, expirado, revogado ou reuse detectado — nesse caso o device é revogado).
DELETE /v1/authentication/biometric/enroll — revogar (autenticado)
Requer sessão válida. Query deviceUid ou deviceId.
DELETE /v1/authentication/biometric/enroll?deviceUid=<...>Response 200: { "success": true }. Deletar o device na tela de dispositivos também revoga.
Modelo de segurança
- No banco só o sha256 do token (nunca o token cru); rotação a cada uso.
- Detecção de reuse: apresentar um token de geração anterior (
versionembutida < atual) revoga o device inteiro (fail-closed). - Vínculo a
device_uid; troca de aparelho não reaproveita. - Expiração dura (~90 dias,
BIOMETRIC_TOKEN_TTL_DAYS) força re-login completo. - A emissão da sessão sem senha usa token-exchange (impersonation) no provedor de identidade (Keycloak) — requer a feature
token-exchangehabilitada e permissão de impersonation no client confidencial.