A step-by-step walkthrough of adding SSO to a Node.js Express app using the WorkOS SSO API.
In this tutorial, we’ll add Single Sign-On to a simple Node.js Express application using the WorkOS SSO API. We’ll use the built-in Test Identity Provider so we can see results immediately without configuring a real IdP.
Time: ~15 minutes
Stack: Node.js + Express + @workos-inc/node
Let’s start by setting up a simple Express project:
mkdir sso-demo && cd sso-demo npm init -y npm install express @workos-inc/node dotenv
Create a .env file with our WorkOS credentials:
WORKOS_API_KEY="sk_test_..." # from API Keys in the dashboard WORKOS_CLIENT_ID="client_..." # from API Keys in the dashboard
In the WorkOS Dashboard, go to Redirects and add http://localhost:3000/callback as a redirect URI. Set it as the default.
WorkOS provides a Test Organization in every staging environment with a mock identity provider. We’ll use this to test SSO without setting up a real IdP.
In the WorkOS Dashboard, go to Organizations and find the Test Organization. Copy its organization ID – it looks like org_....
Add it to the .env file:
WORKOS_API_KEY="sk_test_..." WORKOS_CLIENT_ID="client_..." WORKOS_ORG_ID="org_..." # Test Organization ID
Now let’s create the Express server. Create a file called server.js:
require('dotenv').config(); const express = require('express'); const { WorkOS } = require('@workos-inc/node'); const app = express(); const workos = new WorkOS(process.env.WORKOS_API_KEY); const clientId = process.env.WORKOS_CLIENT_ID; const organizationId = process.env.WORKOS_ORG_ID; const redirectUri = 'http://localhost:3000/callback'; // Store the user profile in memory for this demo let currentUser = null; // Home page app.get('/', (req, res) => { if (currentUser) { res.send(` <h1>Welcome, ${currentUser.firstName} ${currentUser.lastName}!</h1> <p>Email: ${currentUser.email}</p> <p>IdP: ${currentUser.connectionType}</p> <p>Organization ID: ${currentUser.organizationId}</p> <a href="/logout">Sign Out</a> `); } else { res.send(` <h1>SSO Demo</h1> <p>Click below to sign in with SSO.</p> <a href="/login">Sign In with SSO</a> `); } }); // Redirect to WorkOS for SSO app.get('/login', (req, res) => { const authorizationUrl = workos.sso.getAuthorizationUrl({ clientId, organizationId, redirectUri, }); res.redirect(authorizationUrl); }); // Handle the callback from WorkOS app.get('/callback', async (req, res) => { const { code } = req.query; if (!code) { return res.status(400).send('Missing authorization code'); } const { profile } = await workos.sso.getProfileAndToken({ code, clientId, }); // In a real app, we'd create a session here currentUser = profile; res.redirect('/'); }); // Sign out app.get('/logout', (req, res) => { currentUser = null; res.redirect('/'); }); app.listen(3000, () => { console.log('SSO demo running at http://localhost:3000'); });
Let’s start the server:
node server.js
Open http://localhost:3000 in a browser. We should see the home page with a “Sign In with SSO” link.
Click Sign In with SSO. We’re redirected to the WorkOS Test Identity Provider, which looks like a simple sign-in form.
Enter any email and name – the Test IdP accepts any values. Click Sign In.
After authenticating, we’re redirected back to our app and we should see the welcome page with the user’s profile information.
Go to the WorkOS Dashboard and navigate to Organizations > Test Organization. We should see the SSO session listed under the connection details.
We can also go to the Test SSO page in the dashboard to test other login scenarios.
We now have a working Node.js app with: