Extras and going live
Optional features, and the checks before going live.
Link existing users (optional)
If your app already has its own users, they can link their Block-Auth identity to their account. After that, signing in with Block-Auth returns their id in your app as externalId, so you can sign them in as your user.
In your frontend, show LinkBlockAuth to a user who is signed in with your own 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])}
/>
)
}
How you integrate it
In your backend, tell the Block-Auth package who is signed in with your own login (appUser) and save the link (onLinked). With appUser, the package turns on GET /link (is this user linked?) and POST /link (links them, or answers 409 if the identity or your user is already linked):
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 and saveLink are yours: they read and write the link in your database. From then on, every Block-Auth login of that user brings your user ID as externalId in the session user: use it to sign them in as your user.
Ask for a recent login before linking (for example, in the last 10 minutes). To remove a link from your side, call revokeLink(externalId); when a user unlinks from Block-Auth Identity you get the account.unlinked webhook.
Read app data from your server (optional, Node.js)
The browser SDK above never needs apiSecret. Administrative operations — reading your app model, users, roles and logs — run on your own server with the BlockAuthProvider of @block-auth.io/core, which does take apiSecret.
This is the only place apiSecret belongs. It is a server-only credential: it lives in a server environment variable, never in frontend code, and never reaches the browser.
// 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
}
On Node, load the SDK with require. Importing it with import from an ES
module currently fails with Named export 'SHA256' not found.
To know which user logged in, don't use these calls with an address sent by your frontend: use the routes from backend routes, where your backend gets the address from Block-Auth.
Try it and go live
In development, the login only works on your development app's validated domain (one app per environment), not on localhost. Point that domain at your computer with a tunnel to your frontend's dev server, and proxy the /auth/blockauth routes to your backend, so both share the same origin and the session cookie travels with every request. Vite also needs that domain in allowedHosts:
export default {
server: {
allowedHosts: ['dev.your-app.com'],
proxy: { '/auth/blockauth': 'http://localhost:4000' },
},
}
Open your app, press the Block-Auth button, sign in, and check that GET /auth/blockauth/me returns your user.
Before going live:
- Your production app has its own validated domain and keys, and the site uses
https. - The
apiSecretis only in your backend's environment, never in the frontend bundle. /codechecks thatredirectUriis on your origin, and your app creates sessions only from the address returned by/api/auth/token.- The session cookie is
HttpOnly,SecureandSameSite=Lax. - Content Security Policy. If your site sends a CSP, add these sources to it. The login opens in a popup on
auth.block-auth.io, so you don't need to allow Google, Microsoft or the 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: the widget askswss.block-auth.iofor the login link;'self'covers yourauthEndpoint.img-src: the Block-Auth logo in the button.style-src: the widget injects its styles in a<style>tag.- Cross-Origin-Opener-Policy. If your site sends it, use
same-origin-allow-popups, notsame-origin: otherwise your page can't receive the result from the login popup.

