Docs / Switch from Google
Switch from Google to signo: any OpenID Connect library
signo works with any library that supports OpenID Connect discovery and the authorization code flow. signo's own browser tests sign in to a demo site built with openid-client 6.8.8, a certified OpenID Connect library, and the code below comes from that demo.
The examples use login.example.com for signo and example.com for your site. On the public signo, the issuer is https://usesigno.co.uk.
1. Register your site with signo
On the public signo, sign in at https://usesigno.co.uk/account/sites and add your site with its callback URL. On your own signo, run signo clients add on its server, as in Self-hosting. Either way you get an issuer, a client ID and a client secret.
2. What your library needs
| Setting | Value |
|---|---|
| Discovery | https://login.example.com/.well-known/openid-configuration |
| Flow | authorization code (response_type=code) |
| PKCE | required, with S256 |
| Scopes | openid email profile |
| Client authentication | HTTP Basic with the client secret (client_secret_basic) |
| Callback URLs | https, except on localhost |
The ID token carries email, email_verified and name, as Google's does, so code that reads them from Google's ID token keeps working. The userinfo endpoint at /me returns the same claims.
3. Example with openid-client
import * as oidc from 'openid-client';
const config = await oidc.discovery(
new URL('https://login.example.com'),
process.env.SIGNO_CLIENT_ID!,
undefined,
oidc.ClientSecretBasic(process.env.SIGNO_CLIENT_SECRET!),
);
// Sign-in: send the person to signo.
const verifier = oidc.randomPKCECodeVerifier();
const state = oidc.randomState();
const nonce = oidc.randomNonce();
const url = oidc.buildAuthorizationUrl(config, {
redirect_uri: 'https://example.com/callback',
scope: 'openid email profile',
code_challenge: await oidc.calculatePKCECodeChallenge(verifier),
code_challenge_method: 'S256',
state,
nonce,
});
// Callback: exchange the code. Keep verifier, state and nonce in the person's session in between;
// currentUrl is the full URL signo sent the person back to.
const tokens = await oidc.authorizationCodeGrant(config, currentUrl, {
pkceCodeVerifier: verifier,
expectedState: state,
expectedNonce: nonce,
idTokenExpected: true,
});
const { sub, email, name } = tokens.claims();
4. Signing out
To sign the person out of signo as well as your site, send them to the end-session endpoint with their ID token. The return URL must be one of the site's sign-out return URLs.
const logout = oidc.buildEndSessionUrl(config, {
id_token_hint: idToken,
post_logout_redirect_uri: 'https://example.com/',
});
5. Keep the people who signed up with Google
The person's signo sub differs from their Google one. Look existing users up by email the first time they sign in with signo. That is safe, because signo's emails are always verified.