Sign-in button flow
🔑 Auth:
client_idin the tag,client_secretstays 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= yourclient_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 withstate mismatch— see Errors. client_secretnever appears in the page.
Build it
- The flow underneath: Authorization Code flow
- Button + callback walkthrough: Connect with Valyd
- Full working app: Node.js quickstart
- What comes back in the tokens: Tokens
Last updated on