GET /docs/openid-connect · accept: text/markdown200 text/markdown; charset=utf-8 · vary: Accept
# 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](https://usesigno.co.uk/docs/self-hosting.md). 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 ```ts 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. ```ts 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.