Skip to content

Autenticação e autorização

O que é este documento — como o ionCLASS autentica os clientes (tokens Sanctum) e autoriza o que cada um pode fazer, nos dois eixos: o Tipo de usuário (persona/tenancy) e o Papel (permissões finas). Cobre os dois fluxos de onboarding — responsável (mobile) e operador (monitor) — e como o escopo de escola difere entre eles.


1. Autenticação — tokens Sanctum

Todos os clientes REST (mobile do responsável e PWA do operador) autenticam com tokens bearer do Sanctum sob o guard auth:sanctum, enviados em Authorization: Bearer …. O token é emitido ao fim de cada fluxo de login/cadastro. Um 401 em qualquer chamada limpa o token guardado no cliente (MMKV no mobile, localStorage monitor.authToken no monitor).

O logout revoga apenas o token da requisição atual, para que sair em um aparelho não deslogue os outros. O handshake de broadcasting (POST /api/broadcasting/auth) usa o mesmo guard — ver tempo real.


2. Os dois eixos de autorização

A autorização opera em dois eixos ortogonais:

EixoO que éOnde viveO que governa
Tipo de usuárioPersona + escopo de tenancy; conjunto fixo de 6 valores, hierárquicoatributo da contaRecursos estruturais/administrativos (redes, escolas, usuários, papéis), decididos por políticas de acesso
PapelPacote de permissões finas no formato domínio.açãopacote de permissões (spatie)Capacidade operacional fina (ex.: live_monitor.view, arrival_signals.update_status)

Os 6 tipos: dono da plataforma, admin de rede, admin de escola, operador, responsável e terceiro autorizado. Agrupamentos úteis: staff (dono + admin de rede + admin de escola + operador — os que aparecem na tela de usuários), gestores (staff que administra recursos estruturais; o operador é staff mas NÃO é gestor), elevados (dono + admin de rede — cross-tenant, dirigem o enforce de MFA e os gates de criar/inativar escola).

Regra prática: o Tipo diz onde você senta na hierarquia e o que enxerga; o Papel diz quais ações operacionais você pode disparar. Ver a portaria: um operador só transmite/move o quadro se tiver o Papel com live_monitor.view/arrival_signals.update_status — ser operador, por si, não basta.


3. Fluxo do responsável (mobile)

Primeiro acesso do responsável, sem convites e sem aprovação manual. Onboarding = casar CPF + email contra um responsável pré-cadastrado (via importação CSV ou sync do hardware) → código de 6 dígitos por email → confirmar. O responsável pode não ter conta — a conta só é materializada na confirmação do código, não na importação.

  POST v1/auth/register            POST v1/auth/verify-code
        │                                   │
   casa CPF+email  ──▶ envia código   valida código ──▶ materializa a conta
   (código hasheado                    + vincula ao responsável
    em cache; texto                    + emite token Sanctum
    puro por email)

3.1 Passo 1 — POST v1/auth/register

  • Casa o CPF normalizado + email contra um responsável pré-cadastrado (a busca inclui registros excluídos, para reativar quem apagou a conta).
  • Email é opcional no registro. A importação (CSV/hardware) pode não ter email; nesse caso o CPF sozinho prova a identidade e o email informado vira o email da conta. Só se valida o email informado contra o registro quando o registro já tem um.
  • Anti-enumeração: qualquer divergência — CPF desconhecido ou email que não bate — retorna o mesmo 422 genérico ("CPF e email não conferem com nossos registros."). Não há fila de admin para CPF desconhecido.
  • Guarda em cache um código de 6 dígitos hasheado + senha hasheada, com validade configurável (padrão 15 min), e envia o código em texto por email. A chave de cache é derivada de (cpf, email) — a identidade global do responsável — para o passo 2 achar a entrada sem token na URL.
  • Repetir o register regenera um código novo ("reenviar código"). A escola não é enviada pelo app: é derivada dos vínculos do responsável.
  • Um responsável com conta viva já vinculada é bloqueado ("Este responsável já completou o cadastro. Faça login.").

3.2 Passo 2 — POST v1/auth/verify-code

  • Valida o código. Código errado incrementa um contador de tentativas; ao atingir o limite (padrão 5) a entrada é purgada (auditoria de bloqueio por tentativas) e o responsável pede outro. Código certo é one-shot — consumido imediatamente (replays viram "código inválido ou expirado").
  • Numa transação: materializa a conta (papel responsável, ativa, email verificado), vincula ao responsável, grava o consentimento LGPD e emite o token. Se o responsável adotar o email confirmado (não tinha um), ele passa a ser o email do registro. Uma conta excluída é restaurada (mantém id + trilha de auditoria).

3.3 Rotas auxiliares

POST v1/auth/login (email + senha), recuperação de senha por código (auth/password/forgot → 202 sempre, anti-enumeração; auth/password/reset), e auth/password (troca autenticada). Todas com limites de taxa dedicados (cadastro, recuperação de senha e login).


4. Fluxo do operador (monitor)

POST v1/auth/operator-login:

  • Verifica credenciais; em credencial ruim, 422 genérico — não revela se o email é de operador.
  • Exige que o usuário seja operador; um não-operador recebe a mensagem explícita "Apenas operadores podem acessar o monitor." (aqui a mensagem é explícita de propósito, para o legítimo não-operador entender a recusa).
  • Exige que a conta esteja ativa; conta desativada → "Sua conta foi desativada. Entre em contato com o administrador.".
  • Sucesso retorna o token + os dados do operador.

As rotas do operador exigem token Sanctum válido + perfil de operador (operador com escola vinculada, que resolve o contexto da escola). As rotas me/logout não exigem permissão — um operador sem Papel ainda precisa bootar o PWA, ver quem é e sair. O resto do quadro é gated pela permissão live_monitor.view e as transições por arrival_signals.update_status — o Papel, nunca o mero fato de ser operador, decide a autoridade (ver §2).


5. Escopo de escola

O escopo de escola difere por cliente e é a razão de um enviar header e o outro não:

ClienteVínculo com escolaComo enviaResolução no backend
Responsável (mobile)N:NHeader X-School-Id (escola ativa)O backend valida o vínculo com a escola informada
Operador (monitor)1 escolaSem headerO backend resolve a escola pelo token

O mobile também usa X-Pin-Confirmation (PIN de segurança) para ações sensíveis — um gate protege rotas de alta responsabilidade (excluir conta, revogar consentimento biométrico, criar/editar autorizações e passes, editar responsáveis). O PIN é provado por me/pin/verify (→ token de confirmação de curta duração). Detalhes na superfície: app do responsável.


Ver também

Documentação do ionCLASS