Dinaup 2027 ya está llegando: agentes de IA, stock por almacén y todo más rápido. Descubre las novedades →
DinaupBlog
← Volver al blog

Construye tu SaaS sobre la infraestructura de Dinaup

Cómo montar un producto multi-tenant con el SDK .NET: login de usuarios, una empresa por cliente y datos aislados, sin construir backend.

Equipo Dinaup2 de julio de 20266 min de lectura

Quien monta un SaaS B2B escribe dos aplicaciones aunque solo quiera una. La primera es su producto: las pantallas y la lógica que sus clientes pagan. La segunda es el andamiaje que ningún cliente ve: registro de cuentas, login, recuperación de contraseña, 2FA, y la parte que más miedo da: que los datos de una empresa jamás aparezcan en la sesión de otra.

El SDK .NET de Dinaup incluye un patrón para quedarte solo con la primera. Tu aplicación se registra como app externa de la plataforma, y Dinaup le presta la infraestructura: autenticación de usuarios, un espacio de datos aislado por empresa y el modelo tipado de siempre. Este post recorre el patrón completo; la referencia está en la doc de apps multi-tenant.

Lo que no construyes

Con una app externa, estas piezas vienen de serie:

  • Cuentas de usuario. Alta con código de activación, inicio de sesión, 2FA, recuperación y cambio de contraseña. Métodos del SDK, sin pantallas de Dinaup por medio.
  • Multi-tenancy. Cada usuario pertenece a una empresa. Al autenticarse, Dinaup te dice a cuál, y su cliente de datos queda atado a ella.
  • Base de datos. Secciones, informes, escrituras, archivos, anotaciones e histórico de cambios: todo lo del cliente Dinaup, por empresa.
  • Copias de seguridad. Los datos de tus clientes se respaldan en la plataforma. No programas backups ni restauras nada: no hay base de datos tuya que salvar.
  • Secretos. Las credenciales de tu app viven en Vault, no en el código.

Tu parte es la interfaz y el dominio de tu vertical. La suma es un producto completo con el backend ya en producción.

Las tres piezas del patrón

PiezaQué haceCiclo de vida
DinaupExternalAppSettingsIdentifica tu aplicación ante la plataforma (AppId + AppToken).Singleton
DinaupAuthClientAutentica usuarios y devuelve a qué empresa pertenecen.Singleton
MyAppClientCliente de datos de un usuario concreto, atado a su empresa.Uno por sesión

La clave del diseño está en la tercera. MyAppClient hereda de DinaupClientC, así que informes y escrituras funcionan exactamente igual que en cualquier app conectada al SDK. Lo que cambia es el alcance: cada instancia solo llega a los datos de la empresa del usuario que la creó.

Del login al dato

El arranque carga la identidad de la app desde Vault y registra los servicios:

var vault = new Dinaup.Vault.VaultData(vaultUrl, vaultPassword);
vault.Initialize();
var appConfig = new Dinaup.Models.DinaupExternalAppSettings(vault);

builder.Services.AddSingleton(appConfig);
builder.Services.AddSingleton(new Dinaup.Auth.DinaupAuthClient());
builder.Services.AddScoped<SessionUserContext>();

Cuando un usuario inicia sesión, LoginAsync valida sus credenciales y responde con el TenantConnectionKeyword: la clave que identifica su empresa. Con ella construyes su cliente:

var authResponse = await _authClient.LoginAsync(email, password);
if (authResponse == null) throw new Exception("Credenciales inválidas");

DinaupClient = new Dinaup.MyAppClient(_appSettings, authResponse);

A partir de ahí, el código es el SDK de siempre. Leer:

var ventas = new APIVentasC();
await ventas.ExecuteQueryAsync(DinaupClient, page: 1, resultsPerPage: 50);

Escribir:

var wOp = new WriteOperation("", data);
await DinaupClient.RunWriteOperationAsync(VentasES._SectionIDGUID, wOp, false);
wOp.EnsureSuccess();

El mismo informe tipado, la misma WriteOperation. Si ya conectaste una app .NET a tu propia empresa, ya sabes programar contra muchas: la guía de ese primer paso es Conecta tu app .NET a Dinaup.

Una empresa por cliente, un cliente por sesión

El aislamiento entre empresas se apoya en una regla de registro: MyAppClient, y todo servicio que lo use, se registran como Scoped. Cada circuito de usuario recibe su propia instancia, atada a su empresa. Un singleton aquí compartiría la sesión de una empresa con los usuarios de otra.

// Uno por usuario/circuito. Nunca Singleton.
builder.Services.AddScoped<SessionUserContext>();
builder.Services.AddScoped<VentasService>();

Para que la sesión sobreviva a recargas, el navegador solo guarda una cookie HttpOnly con un id de sesión. El estado real (la empresa y el email del usuario) se serializa en el almacén clave-valor de la plataforma, MyAppKVClient, bajo ese id. Al volver, la app lee la cookie, recupera el estado del KV y reconstruye el cliente. El código completo está en la doc.

En procesos sin sesión interactiva (importaciones, tareas programadas), DinaupContext.WithUser(userId) atribuye las operaciones a un usuario concreto: autor del alta, histórico y anotaciones quedan a su nombre.

La sesión no vive en tu servidor: despliega los nodos que quieras

Ese detalle de guardar la sesión en el KV tiene una consecuencia que vale una sección: tu app queda stateless. Ni los datos ni las sesiones viven en el proceso; todo lo recuperable está en la plataforma.

  • El mismo contenedor desplegado en dos, tres o N nodos detrás de un balanceador. La cookie de sesión vale en cualquiera, porque el estado se lee del KV.
  • Si un nodo cae, otro atiende la siguiente petición sin que el usuario vuelva a hacer login.
  • Sin sesiones pegajosas en el balanceador, sin un Redis propio que administrar, sin disco que replicar.

Alta disponibilidad con la pieza más barata del catálogo: un id en una cookie y un GetKVAsync.

Las cuentas de tus usuarios, desde tu interfaz

El registro, la activación y las contraseñas se gestionan con métodos del cliente. Tu formulario, tu diseño; Dinaup guarda las credenciales:

NecesitasMétodo
Crear una cuentaSession_RegisterAccountAsync y su código de activación
ActivarlaSession_ConfirmAccountRegistrationAsync
Iniciar sesión con 2FASession_SignInAsync + Session_CheckTwoFactor
Recuperar contraseñaSession_CreatePasswordRecoveryCodeAsync + Session_ChangePasswordWithCodeAsync

Todas reciben el userAgent y la IP del usuario final, para que el acceso quede registrado con su origen real y no con el del servidor de tu app.

Lo que sí pones tú

  • La interfaz. Tu web o tu app, con tu marca. Dinaup no impone framework: el SDK es un paquete .NET.
  • El dominio. Las secciones y los informes de tu vertical, tipados en tu paquete MyDinaup. Cómo funciona ese modelo: el SDK .NET por dentro.
  • La configuración de tu app. Para estado propio del producto (flags, ajustes globales, las sesiones de tus usuarios) tienes MyAppKVClient, un almacén clave-valor que además sirve de health check de la conexión.

Preguntas frecuentes

Siguiente paso

  • Apps multi-tenant — la referencia del patrón: montaje, login, cuentas y almacén clave-valor.
  • Cliente Dinaup — informes, filtros, escrituras, archivos y anotaciones.
  • Vault — las credenciales de tu app, fuera del código.
  • MyDinaup — tu modelo de datos convertido en clases.

Sigue leyendo