Extras y producción

Funciones opcionales y las comprobaciones antes de salir a producción.

Si tu app ya tiene sus propios usuarios, pueden vincular su identidad de Block-Auth a su cuenta. A partir de ahí, iniciar sesión con Block-Auth devuelve su id en tu app como externalId, para que entren como tu usuario.

En tu frontend, muestra LinkBlockAuth a un usuario que ha iniciado sesión con tu propio login:

import { LinkBlockAuth } from '@block-auth.io/react'

const messages = {
  already_linked: 'This Block-Auth account is already linked to another user.',
  not_signed_in: 'Sign in again to link your account.',
  failed: 'Linking failed, try again.',
}

export function LinkAccount() {
  return (
    <LinkBlockAuth
      onLinked={() => window.location.reload()}
      onError={(reason) => alert(messages[reason])}
    />
  )
}

Cómo lo integras

En tu backend, dile al paquete de Block-Auth quién ha iniciado sesión con tu propio login (appUser) y guarda el vínculo (onLinked). Con appUser, el paquete activa GET /link (¿está vinculado este usuario?) y POST /link (lo vincula, o responde 409 si la identidad o tu usuario ya están vinculados):

export const routes = new BlockAuthRoutes({
  apiKey: BLOCKAUTH_API_KEY,
  apiSecret: BLOCKAUTH_API_SECRET,
  appUrl: APP_URL,
  appUser: async ({ session }) => {
    const id = session.get('userId')
    return id ? { id, linked: await isLinked(id) } : null
  },
  onLinked: (id, user) => saveLink(id, user.address),
})

isLinked y saveLink son tuyas: leen y escriben el vínculo en tu base de datos. Desde entonces, cada login de ese usuario con Block-Auth trae el ID de tu usuario como externalId en el usuario de la sesión: úsalo para que entre como tu usuario.

Pide un login reciente antes de vincular (por ejemplo, de los últimos 10 minutos). Para quitar un vínculo desde tu lado, llama a revokeLink(externalId); cuando un usuario desvincula desde Block-Auth Identity recibes el webhook account.unlinked.

Lee los datos de tu app desde tu servidor (opcional, Node.js)

El SDK de navegador de arriba nunca necesita apiSecret. Las operaciones de administración (leer el modelo de tu app, usuarios, roles y logs) se ejecutan en tu propio servidor con el BlockAuthProvider de @block-auth.io/core, que sí recibe apiSecret.

Este es el único sitio donde debe estar apiSecret. Es una credencial solo de servidor: vive en una variable de entorno del servidor, nunca en el código del frontend, y nunca llega al navegador.

// server.js — runs on YOUR Node backend (CommonJS), never bundled into the frontend
const { BlockAuthProvider } = require("@block-auth.io/core");

const provider = new BlockAuthProvider(
  process.env.BLOCKAUTH_API_KEY,    // publishable key
  process.env.BLOCKAUTH_API_SECRET, // server-only secret — keep off the frontend
);

async function main() {
  // Connect the backend to the Block-Auth provider (blockchain + API), then authenticate.
  await provider.connect();
  await provider.signin();

  // Privileged, admin-level operations run here on the server:
  const app = await provider.app();     // your app model
  const users = await provider.users(); // your app's users and their roles
}

Para saber qué usuario ha iniciado sesión, no uses estas llamadas con una dirección enviada por tu frontend: usa las rutas del rutas del backend, en el que tu backend obtiene la dirección de Block-Auth.

Pruébalo y pasa a producción

En desarrollo, el login solo funciona en el dominio validado de tu app de desarrollo (una app por entorno), no en localhost. Apunta ese dominio a tu ordenador con un túnel hacia el servidor de desarrollo de tu frontend, y redirige las rutas /auth/blockauth a tu backend con un proxy, para que compartan origen y la cookie de sesión viaje en cada petición. Vite necesita además ese dominio en allowedHosts:

export default {
  server: {
    allowedHosts: ['dev.your-app.com'],
    proxy: { '/auth/blockauth': 'http://localhost:4000' },
  },
}

Abre tu app, pulsa el botón de Block-Auth, inicia sesión y comprueba que GET /auth/blockauth/me devuelve tu usuario.

Antes de salir a producción:

  • Tu app de producción tiene su propio dominio validado y sus claves, y la web usa https.
  • El apiSecret solo está en el entorno de tu backend, nunca en el bundle del frontend.
  • /code comprueba que redirectUri está en tu origen, y tu app solo crea sesiones a partir de la dirección que devuelve /api/auth/token.
  • La cookie de sesión es HttpOnly, Secure y SameSite=Lax.
  • Content Security Policy. Si tu web envía una CSP, añade estos orígenes. El login se abre en un popup en auth.block-auth.io, así que no necesitas permitir Google, Microsoft ni las wallets:

Content-Security-Policy

connect-src 'self' https://wss.block-auth.io;
img-src 'self' https://dashboard.block-auth.io;
style-src 'self' 'unsafe-inline';
  • connect-src: el widget pide el enlace de login a wss.block-auth.io; 'self' cubre tu authEndpoint.
  • img-src: el logo de Block-Auth del botón.
  • style-src: el widget inyecta sus estilos en una etiqueta <style>.
  • Cross-Origin-Opener-Policy. Si tu web la envía, usa same-origin-allow-popups, no same-origin: si no, tu página no puede recibir el resultado del popup de login.