/projects/dietbox-b2c
← Todos os projetosDietbox B2C
Uma base de identidade, dois públicos, jornadas de login customizadas.
Engenheiro de Software Sênior, depois Head de Tecnologia · 2021–2024

Visão geral
Um único sistema de identidade em Azure AD B2C carregando dois públicos que não dividem nada além da conta: a nutricionista que assina e paga, e o paciente que chega por convite de quem o atende. Cinco clientes fazem login por ele — o app da nutricionista, o app Android do paciente, o app iOS do paciente, o produto web que os dois públicos usam e o checkout — em três plataformas e dois tenants. Três anos de jornadas de login customizadas, provedores federados, migração silenciosa da base legada e revogação de sessão que alcança todo navegador aberto.
O que eu fiz
É o que mais tem de mim em toda a Dietbox: escrevi metade dos commits ao longo de três anos, cobrindo as jornadas de login dos dois públicos.
- Os dois conjuntos de políticas — um para a profissional, um para o paciente — cada um com sua própria jornada de cadastro, login e redefinição de senha.
- Federação com Google, Facebook e Apple, cada uma mapeada por seu próprio exchange profile para uma claim de subject comum.
- A migração no primeiro login, que move um usuário da base legada para o diretório na própria jornada em que ele entra.
- Revogação de sessão: um carimbo no usuário comparado com o momento de emissão do token, para que uma troca de senha ou uma revogação administrativa encerre a conta em todo lugar.
- As páginas de login customizadas, um conjunto por público, servidas e preenchidas em tempo de execução.
O problema
Um login hospedado dá a um produto uma única jornada. Este precisava de várias: uma assinante se cadastrando e pagando, um paciente chegando por convite sem senha para definir, uma aluna de academy, e uma recepcionista agindo em nome de outra pessoa — tudo sobre um único diretório, sem quatro bases de usuário separadas para manter sincronizadas.
Em números
A contagem de linhas é uma contagem simples sobre os arquivos de política versionados; a proporção de commits vem do repositório.
Arquitetura
Dois conjuntos de políticas independentes ficam acima de um diretório único, e tudo a jusante confia nos tokens que eles emitem.
- ClientsDois apps do paciente, o app da nutricionista, o produto web e o checkout — todos começam por aqui.
- Practitioner policiesJornadas de cadastro, login, assinante e academy para o público de nutricionistas.
- Patient policiesCadastro e login para o público de pacientes, convidados em vez de autocadastrados.
- DirectoryUma única base de usuários abaixo dos dois conjuntos de políticas, com contas locais e federadas.
- Auth serviceValida os tokens que este sistema emite. Leituras e escritas no próprio diretório passam por um pacote de gateway compartilhado do qual vários serviços da plataforma dependem.
- Custom UI pagesMarcação estática, um conjunto por público, servida pela plataforma de identidade e preenchida em tempo de execução.
A jornada de login
Cada etapa abaixo corresponde a um technical profile que existe na política — é a orquestração como está escrita, não uma simplificação dela.
- Sign-inCredenciais locais, ou um provedor federado — Google, Facebook ou Apple — trocado por uma claim de subject comum.
- Legacy checkÉ um usuário da base legada que ainda não foi migrado?
- MigrationSe sim, a conta é escrita no diretório com um identificador de segurança alternativo que a liga de volta à credencial legada — na mesma jornada do login, não numa etapa separada.
- EntitlementA conta está habilitada, e ela pertence a uma jornada com restrição — assinante, academy — que exige um direito de acesso ativo?
- TokenUm token é emitido, carimbado com o momento a partir do qual o registro de segurança do usuário é válido.
O que faz
- Cadastro e login para cada público, na própria política e nas próprias páginas com marca.
- Mais dois logins com bloqueio de acesso para a nutricionista além do comum — assinantes e alunos da academy —, cada um com política própria.
- Recuperação de senha, troca de senha e edição de perfil, cada um um ponto de entrada próprio, por público.
- Uma troca direta de credenciais para os apps nativos, ao lado do redirect de navegador que os clientes web usam — mesmo diretório, mesmas regras, dois formatos.
- Renovação de refresh token como jornada própria, uma por tipo de acesso, para que um token renovado seja reconferido em vez de presumido válido.
- Login federado com três provedores, cada um trocado por uma claim de subject comum.
- Migração silenciosa da base legada durante a própria jornada de login do usuário.
- Páginas com marca por público, um conjunto para a profissional e um para o paciente.
- Bloqueios de direito de acesso para jornadas de assinante e academy, aplicados dentro do fluxo de login em vez de depois dele.
Decisões de engenharia
Políticas customizadas em vez de um login hospedado
Um login hospedado dá uma única jornada. Este produto precisava de uma assinante se cadastrando e pagando, um paciente chegando por convite, uma aluna de academy e uma recepcionista — sobre um único diretório, sem quatro bases de usuário para manter sincronizadas. Escrever a política diretamente foi a única forma de ter jornadas com restrição e migração no primeiro login sem bifurcar a base de usuários.
Migração como efeito colateral do login
Ninguém foi solicitado a redefinir senha ou se recadastrar. O usuário vive um login; o sistema vive uma migração, escrevendo a conta no diretório e ligando-a de volta à credencial legada na mesma jornada.
Revogação que alcança sessões abertas
Um token apenas não renovável não está revogado. Comparar o momento de emissão do token com um carimbo no registro do usuário é o que faz "encerrar a conta em todo lugar" significar isso de fato, e não "impedir que a conta consiga um novo token da próxima vez".
Duas formas de entrar, porque um celular não abre um redirect
Três dos cinco clientes são apps nativos, e um app nativo que loga o usuário por redirect de navegador é uma experiência ruim e pior ainda de recuperar. Então o mesmo diretório responde a dois formatos de requisição: a jornada de redirect que o produto web e o checkout usam, e uma troca direta de credenciais que os apps usam, cada uma com sua própria renovação de refresh token. Os bloqueios de acesso e o comportamento de migração ficam na política, não no cliente, para que os dois formatos não derivem para dois conjuntos de regras diferentes.
Um diretório, várias jornadas
Políticas separadas por público sobre uma única base de usuários compartilhada, em vez de uma política com ramificação por público ou várias bases para reconciliar. Os públicos compartilham uma identidade, não um formulário.