Como usar Auth0 para sua plataforma B2B multi-tenant com Next e Vercel
Me deparei com o seguinte problema: construir uma plataforma que deveria servir diversas empresas de forma isolada e customizada, ou seja, uma plataforma B2B multi-tenant.
Então construí uma aplicação em Next.js que utiliza o Auth0 para autenticação e a Vercel para hospedagem com subdomínios para cada cliente/tenant.
Vamos entender melhor esses conceitos:
Multi-tenant
Multi-tenant é uma arquitetura em que uma única instância de um software (um código fonte) serve vários clientes ou "inquilinos", no nosso caso, empresas. Essa abordagem permite que múltiplos usuários compartilhem os mesmos recursos e dados, mas de maneira isolada e segura. Para isso, é crucial implementar controles rigorosos de acesso e segregação de dados para garantir que os inquilinos não possam acessar os dados uns dos outros.
- Banco de dados separado para cada inquilino: Cada inquilino tem seu próprio banco de dados independente. Isso oferece o mais alto nível de isolamento, mas pode ser mais caro e complexo de gerenciar.
- Esquema separado para cada inquilino: Cada inquilino tem seu próprio esquema dentro de um banco de dados compartilhado. Isso oferece um bom equilíbrio entre isolamento e eficiência, mas requer cuidado na gestão de esquemas.
- Tabelas compartilhadas com coluna de inquilino: Todos os inquilinos compartilham as mesmas tabelas, e uma coluna de identificação do inquilino é usada para separar os dados. Essa abordagem é altamente eficiente em termos de recursos, mas o isolamento e a segurança dos dados podem ser mais desafiadores.
- Virtualização a nível de banco de dados: Utilizando tecnologias de virtualização, é possível criar instâncias virtuais separadas para cada inquilino dentro de um único banco de dados. Isso pode oferecer um bom equilíbrio entre isolamento e eficiência.
A arquitetura multi-tenant é comumente usada em aplicações SaaS (Software como Serviço), permitindo uma escalabilidade eficiente e uma personalização mais fácil para atender às necessidades específicas de cada cliente.
Subdomínios
A ideia é termos debaixo de nosso domínio principal subdomínios que vão representar os tenants, esses subdomínios irão apontar para mesma aplicação:
*.meudominio.com.br
- empresa1.meudominio.com.br
- empresa2.meudominio.com.br
Auth0 - Autenticação
A autenticação é um componente essencial em qualquer plataforma, ainda mais em se tratando de empresas. Afinal, a segurança dos dados é uma preocupação prioritária para garantir a confiabilidade e a integridade das informações entre os diferentes usuários de uma plataforma B2B.
Nesse sentido, o uso de um serviço de autenticação robusto e confiável é crucial. O Auth0 é um desses serviços que fornece uma solução completa para autenticação e autorização em diversas aplicações.
O Auth0 tem alguns conceitos:
- Aplicações: Representa um cliente ou uma entidade que pode solicitar tokens de autenticação. Pode ser um aplicativo móvel, um aplicativo da web, um servidor de backend, etc.
- Tenant: Refere-se a uma instância isolada e dedicada da plataforma que um cliente pode controlar e configurar. Normalmente utilizados para representar ambientes como desenvolvimento, sandbox e produção, etc.
- Organizações: É uma abstração que facilita o gerenciamento de colaboração e acesso em um contexto de negócios. É especialmente útil para representar empresas ou equipes que usam aplicações SaaS (Software as a Service).
Mãos à obra
1. Criar uma aplicação: Primeiro você precisa criar sua conta no Auth0 e criar sua primeira aplicação.
Você pode customizar o HTML, CSS e JS dessa tela de login. Saiba mais aqui.
Após fazer a primeira autenticação, você vai receber o token com as informações do usuário:
2. Configure sua aplicação: Por questões de segurança o auth0 nos pede algumas urls:
- Application Login URI: Essa é a url de login principal, por onde os usuários serão convidados e poderão fazer login. Infelizmente, não temos uma url por organização e sim uma global por aplicação. Portanto, precisaremos fazer o direcionamento via código para url do tenant/organização específico.
- Allowed Callback URLs: São as urls permitidas para serem chamadas após o login.
- Allowed Logout URLs: São as urls permitidas para serem chamadas após o logout.
- Allowed Web Origins: São as urls permitidas para fazer chamadas em funções específicas do Auth0.
3. Guarde algumas informações: Com sua aplicação criada, você vai precisar do domínio e do Client ID.
Além disso, você vai precisar da API de Audience, encontrada nesse link.
Fluxo de Autenticação
Ao acessar qualquer subdomínio, a aplicação não sabe qual tenant precisa configurar. Portanto, precisamos buscar as informações do tenant em um serviço backend. Essas informações podem ser o endpoint do backend, nome do tenant, logo, feature flags, etc, porém o mais importante para este exemplo é o ID da organização no Auth0.
Com essa informação podemos direcionar o usuário para a organização correta, sem precisar que o usuário insira a organização.
Como um mesmo usuário no Auth0 pode estar conectado a mais de uma organização, para o fluxo de login funcionar da maneira acima, precisamos fazer algumas configurações.
4. Na página da sua aplicação: selecione a aba organização, depois, Business User em tipos de usuários e Prompt for Organization em fluxo de login.
Essa funcionalidade permite selecionar a organização caso tenha mais de uma e também caso você inicie o fluxo de login sem indicar qual organização está tentando logar. Imagine que estejamos logando de nosso domínio raiz: meudominio.com.br.
Seguindo nosso fluxo, após o login e a organização selecionada, somos direcionados de volta para nossa aplicação. Então, precisamos buscar o token JWT do nosso usuário logado e direcioná-lo para a url correta da organização, esta url precisa estar no JWT. Para isso, vamos seguir alguns passos:
5. Navegue até a seção de Actions: No painel de navegação à esquerda, clique em Actions e, em seguida, clique no botão Flows.
6. Selecione o flow de login: Clique no fluxo de login para modificá-lo.
7. Crie uma ação: Crie uma ação com gatilho Login / Post Login. Coloque o nome Add metadata to access token.
8. Insira o script que irá adicionar os metadados ao access token: Certifique-se de substituir my_application pelo namespace que você deseja usar. O namespace deve ser uma URL, mas não precisa ser uma URL acessível. Por exemplo, você pode usar https://seu_dominio.com.
Você pode olhar o código aqui.
9. Salve a regra: Arraste a ação para o diagrama e clique no botão Deploy para salvar sua regra.
Notas Importantes
- O uso de namespaces personalizados é uma prática recomendada para evitar colisões com as reivindicações padrão do JWT.
- As informações que você está adicionando ao token devem ser consideradas sensíveis, então certifique-se de que elas são tratadas com segurança em seu aplicativo.
Agora, sempre que um usuário se autenticar, as informações de perfil e organização serão incluídas nos tokens de acesso e identificação, e você poderá acessá-las em seu aplicativo conforme necessário.
10. Criar uma organização: Agora, vamos criar uma organização (tenant). Lembrando que você pode automatizar todas essas configurações por meio das APIs do Auth0. Na aba organization -> Create Organization, coloque o nome e o display name:
11. Adicione informações da organização: Agora, vamos na página da organização e podemos adicionar metadados como tenant_url e tenant_name. Podemos adicionar também outros dados customizados que sua aplicação possa precisar para customizar uma organização.
12. Habilite a conexão para sua organização: Ainda na página da organização, vá na aba de Connections e clique em Enable Connections.
Selecione Username-Password-Authentication. Se você quiser habilitar a autenticação usando a conta do Google, pode fazer depois.
Você pode escolher se vai autorizar qualquer usuário entrar na organização ou não.
Pronto, agora você tem sua conexão configurada:
13. Convide seus usuários: Na aba Invitations você pode convidar os usuários para sua organização:
Código para fluxo de login
O primeiro passo do nosso fluxo de autenticação é buscar as configurações dos tenant/organização. Para isso, criamos um contexto chamado TenantContext que retorna as configurações baseado na URL atual da aplicação.
Você pode olhar o código aqui.
No exemplo acima, estamos recuperando as configurações por meio de um objeto, mas, podemos ter uma api para este fim.
Depois de ter as configurações do tenant/organização podemos configurar nossa aplicação e chamar a função de login do Auth0 indicando o ID da organização atual.
Você pode olhar o código aqui.
Perceba que esse contexto é um wrapper do contexto oficial do Auth0, para que possamos suportar o nosso fluxo B2B.
A aplicação completa está nesse repositório.
Ao receber um convite, o usuário será redirecionado para a seguinte página:
Ao aceitar o convite, o usuário deverá criar uma senha.
E será redirecionado para a URL da organização que foi convidado:
Para acessar a aplicação desse tutorial, acesse uma das empresas e faça o login/signin.
https://empresa1.b2b.abilioazevedo.com.br/
https://empresa2.b2b.abilioazevedo.com.br/
Após isso, se você acessar a URL principal:
https://b2b.abilioazevedo.com.br/
Você poderá fazer o login e se tiver acesso às duas empresas, deverá escolher qual você irá logar:
O Auth0 tem melhorado as funcionalidades para suportar melhor os fluxos B2B. Uma futura melhoria é ter URLs de login por organização e não global por aplicação.
Portanto, mais do que dominar uma ferramenta específica como o Auth0, precisamos entender os fluxos e conceitos, para escolher melhor nossas soluções. Espero que esse artigo seja útil para suas futuras aplicações.
Até a próxima, pessoal!
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.