Tu backend
Añade las rutas que llama el widget y recibe los webhooks. Con el paquete de Block-Auth para tu servidor es casi todo configuración: canjea el código de login, guarda la sesión y verifica los webhooks por ti. Si lo prefieres, puedes escribirlo tú mismo.
Cómo lo integras
Añade las rutas del backend
Instala el paquete de Block-Auth para tu servidor:
npm install @block-auth.io/node express express-session
Crea BlockAuthRoutes con tus claves y la URL de tu frontend, y móntalo en tu servidor:
import express from 'express'
import session from 'express-session'
import { BlockAuthRoutes } from '@block-auth.io/node'
import { blockauthRouter } from '@block-auth.io/node/express'
const { APP_URL, BLOCKAUTH_API_KEY, BLOCKAUTH_API_SECRET, SESSION_SECRET } = process.env
export const routes = new BlockAuthRoutes({
apiKey: BLOCKAUTH_API_KEY,
apiSecret: BLOCKAUTH_API_SECRET,
appUrl: APP_URL,
})
export const app = express()
app.use(
session({
secret: SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, sameSite: 'lax', secure: APP_URL.startsWith('https') },
}),
)
app.use(blockauthRouter(routes))
app.use(express.json())
app.listen(4000)
Y ya está. Tu servidor responde estas rutas bajo /auth/blockauth, la ruta que el widget llama por defecto:
| Ruta | Qué hace |
|---|---|
POST /code | Canjea el código de login en Block-Auth, crea la sesión y devuelve { address, did, roles } |
GET /me | Devuelve el usuario con sesión, o 401 |
POST /logout | Cierra la sesión en tu app y en Block-Auth |
GET y POST /link | Vincula tus usuarios existentes (solo con la opción appUser) |
POST /webhook | Recibe los webhooks |
Lo que el paquete ya hace por ti:
- Solo se fía de Block-Auth. El usuario sale siempre de canjear el código con tu
apiSecret, y elredirectUritiene que estar enappUrl. Si tu frontend vive en varios orígenes, pasaallowedOrigins(una lista) en su lugar. - Bloquea peticiones falsificadas. Solo acepta
POSTcon cuerpo JSON, así otra web no puede iniciar sesión a tus usuarios con un formulario. - Mantiene la sesión corta y limpia. Renueva el ID de sesión en cada login y la termina cuando caduca la firma del usuario en Block-Auth (
signedExpiredAt). Para terminarla antes, ponmaxSessionSeconds(MaxSessionDurationen .NET). - Cierra sesión en todas partes.
POST /logoutcierra también las sesiones de Block-Auth del usuario para tu app, y conserva el resto de datos de tu sesión. - Verifica cada webhook. Firma, hora y
apiKey, antes de llamar a tu código.
APP_URL es el origen de tu frontend, el de tu dominio validado (por
ejemplo https://your-app.com). El SDK calcula el hash del apiSecret:
pásalo tal cual sale del Dashboard. En Node.js, monta blockauthRouter
antes de express.json(), para que el webhook se verifique con el cuerpo
original. Si tu servidor está detrás de un proxy que termina el https,
añade app.set('trust proxy', 1) o Express no enviará la cookie segura.
Si tus rutas tienen que vivir bajo otra ruta, ponla en basePath y la misma como authEndpoint en el widget. Para desactivar una ruta que no usas, pasa routes: { link: false } (en .NET, añádela a DisabledRoutes). Las opciones van en snake_case en Python y en PascalCase en .NET.
Usa la sesión en tus rutas
A partir de aquí, la sesión es la fuente de verdad. Lee el usuario antes de hacer nada que necesite un usuario con sesión o un rol. Recibes null si no hay sesión, si caducó o si la cerró un webhook:
import { expressSessionStore } from '@block-auth.io/node/express'
const currentUser = (req) => routes.currentUser({ session: expressSessionStore(req) })
const requireRole = (slug) => async (req, res, next) => {
const user = await currentUser(req)
if (!user) return res.status(401).end()
if (!user.roles.some((role) => role.slug === slug)) return res.status(403).end()
next()
}
app.delete('/api/orders/:id', requireRole('acme-x7k2p9'), deleteOrder)
El usuario tiene address, did, roles ({ name, slug }), externalId (el ID de tu usuario, si está vinculado), loggedInAt, expiresAt (segundos Unix) y data. En .NET los roles son también claims de rol con el slug. Usa el slug del rol, no el nombre: mira Roles.
Para guardar tus propios datos en la sesión, o para rechazar un login, añade onLogin(user): devuelve un objeto para guardarlo como data, o false para rechazar al usuario (sale también de Block-Auth). En .NET, AuthorizeLogin decide y OnLogin devuelve los datos. onLogout(user) se ejecuta cuando el usuario cierra sesión.
Recibe los webhooks
Block-Auth llama a tu backend cuando un usuario cierra la sesión de tu app desde Block-Auth (signout) o desvincula tu app (account.unlinked), para que también puedas cerrar su sesión.
Así llega a tu página un cierre de sesión hecho en Block-Auth (Identity, la extensión u otro dispositivo):
- 1Block-AuthEl usuario cierra sesión
- 2Block-Auth → Tu backendPOST /webhook · signout
- 3Tu backendGuarda el cierre
- 4Tu frontend → Tu backendGET /me al volver o cada 60 s
- 5Tu backend → Tu frontend401
- 6Tu frontendMuestra al usuario sin sesión
Widget de Block-Auth
Tu sesión
Lo aloja Block-Auth
- 1El usuario cierra sesión
- 2POST /webhook · signout
- 3Guarda el cierre
- 4GET /me al volver o cada 60 s
- 5401
- 6Muestra al usuario sin sesión
- En el Dashboard, abre tu aplicación y ve a Autenticación. En el tercer campo de URL, que aparece como «Cuando falla el inicio de sesión», escribe la ruta
/auth/blockauth/webhook(tu dominio ya viene puesto).
- Dile al paquete cómo recordar un cierre de sesión y cómo comprobarlo.
POST /webhookya existe: verifica la petición y llama aonSignoutuonUnlinked. DespuésisRevokedcierra cada sesión que empezó antes de ese cierre:
saveSignout, lastSignout y removeLink son tuyas: guárdalo en tu base de datos o en una caché compartida como Redis, para que lo vean todas las instancias de tu servidor. address llega en minúsculas, e iat y loggedInAt son segundos Unix.
isRevokedse ejecuta en cadaGET /mey cada vez que lees el usuario. El widget consulta/meal volver a la pestaña y cada minuto, así que la página cierra la sesión sola.- Para rechazar un envío repetido, añade
isReplay(jti)y devuelvetruesi ya viste esejti.

