Express session middleware
Add hosted login and an encrypted session cookie to Express with ScalekitAuth
Use ScalekitAuth from @scalekit-sdk/node/express to add hosted login, an encrypted sk_session cookie, token refresh, and logout.
Typical flow: install @scalekit-sdk/node 2.12.0 or later, mount auth.router, and guard one route with auth.requiresAuth. Use the methods below to change paths, logout, or pass an existing ScalekitClient.
Register these URLs in the Scalekit Dashboard under Authentication > Redirects before you test:
| Dashboard field | Must match |
|---|---|
| Redirect URI | redirectUri exactly, for example http://localhost:5001/callback |
| Post Logout Redirect URI | Absolute URL after full logout, for example http://localhost:5001/ |
| Initiate Login URL | Login path, for example http://localhost:5001/login |
Store credentials in environment variables. Never hard-code secrets.
SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.comSCALEKIT_CLIENT_ID=skc_...SCALEKIT_CLIENT_SECRET=...COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32REDIRECT_URI=http://localhost:5001/callbackKeep COOKIE_ENCRYPTION_SECRET identical on every server instance. The SDK does not ship a default.
Install the package
Section titled “Install the package”npm install @scalekit-sdk/node expresscookie-parser is optional. ScalekitAuth reads the Cookie header when req.cookies is missing.
Protect a route
Section titled “Protect a route”import express from 'express';import { ScalekitAuth } from '@scalekit-sdk/node/express';
const auth = new ScalekitAuth({ envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, clientId: process.env.SCALEKIT_CLIENT_ID, clientSecret: process.env.SCALEKIT_CLIENT_SECRET, redirectUri: process.env.REDIRECT_URI, cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET,});
const app = express();app.use(auth.router);
app.get('/account', auth.requiresAuth, (req, res) => { res.json({ sub: req.scalekitUser?.sub });});
app.listen(5001);Open http://localhost:5001/account. A missing session returns 302 to /login?returnTo=/account, not a JSON 401. After login, the callback restores /account.
req.scalekitUser is access-token claims. sub is always present. email appears only when you add it as a custom access-token claim.
constructor
Section titled “constructor”#constructor
Creates the Express session helper and builds auth.router for /login, /callback, and /logout.
Existing client. When omitted, the constructor builds one from envUrl, clientId, and clientSecret.
Scalekit environment URL.
Application client ID.
Application client secret.
Exact Redirect URI registered in the dashboard.
Secret used to encrypt sk_session. Generate with openssl rand -base64 32.
Session cookie name.
Path served by auth.router for login.
Path served by auth.router for the OAuth callback.
Path served by auth.router for logout.
Fallback path after login when returnTo is absent.
Where logout lands. Defaults to postLoginRedirect. Register the absolute URL as Post Logout Redirect URI.
When true, logout ends the Scalekit session with id_token_hint. Set false to clear only the local cookie.
Helper with router and requiresAuth.
const auth = new ScalekitAuth({ envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, clientId: process.env.SCALEKIT_CLIENT_ID, clientSecret: process.env.SCALEKIT_CLIENT_SECRET, redirectUri: process.env.REDIRECT_URI, cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET,});
app.use(auth.router);requiresAuth
Section titled “requiresAuth”#asyncrequiresAuth
Express middleware that requires a valid session. Refreshes the cookie about 10 seconds before expiry. Redirects to loginPath when the session is missing or invalid.
Incoming request. On success, sets req.scalekitUser to access-token claims.
Outgoing response. May receive a refreshed sk_session cookie.
Called only when the session is valid.
Completes the request, or sends 302 to /login?returnTo=....
app.get('/billing', auth.requiresAuth, (req, res) => { res.send(`Hello ${req.scalekitUser.sub}`);});router
Section titled “router”#router
Express router that serves loginPath, callbackPath, and logoutPath. Mount it before protected routes.
Router registered by the constructor.
app.use(auth.router);