Skip to Content
Docs

Sign-in button flow

🔑 Auth: client_id in the tag, client_secret stays on your backend · 👤 This IS the login — the button runs the Authorization Code flow for you

The drop-in button (https://idp.valyd.work/signin/client.js) is a front end for the Authorization Code flow. It generates state and nonce, builds the authorize URL, and redirects the user to Valyd. The code exchange still happens on your backend with your client_secret.

<script src="https://idp.valyd.work/signin/client.js" async></script> <div class="valyd-signin" data-client-id="YOUR_CLIENT_ID" data-redirect-uri="https://yourapp.com/auth/valyd/callback" data-scope="profile verifications"></div>

Redirect mode

Before redirecting, the button stores the generated values in valyd_oidc_state and valyd_oidc_nonce cookies so your callback route can compare them.

Backend handler (the whole thing):

app.get("/auth/valyd/callback", async (req, res) => { const { user } = await valyd.handleCallback(req.url, { expectedState: req.cookies.valyd_oidc_state, // the button set this cookie nonce: req.cookies.valyd_oidc_nonce, }); res.redirect("/dashboard"); });

Security notes

  • Your backend owns the code exchange, ID-token validation (RS256/JWKS, nonce, aud = your client_id), and session creation. Never accept tokens minted anywhere but your own backend.
  • Codes are single-use and expire fast — send them to your backend immediately.
  • The cookie comparison is the CSRF check; if cookies are being blocked (third-party contexts, SameSite), legitimate logins fail with state mismatch — see Errors.
  • client_secret never appears in the page.

Build it

Last updated on