Redirect Flow
Use the redirect flow when you want the SDK to drive a standard OAuth 2.0 authorization-code redirect cycle for your Express application.
Prerequisites
expresscookie-parser- an application configured in ThunderID
- a redirect route such as
http://localhost:3000/login
Middleware Order
Mount middleware in this order:
cookie-parser()express.json()if you also need JSON request parsingthunderID(config)- Route handlers that use
handleSignIn(),handleSignOut(), orprotect()
Example
index.js
const express = require('express');
const cookieParser = require('cookie-parser');
const {thunderID, handleSignIn, handleSignOut, protect} = require('@thunderid/express');
const app = express();
const port = 3000;
app.use(cookieParser());
app.use(express.json());
app.use(
thunderID({
baseUrl: 'https://localhost:8090',
clientId: '<your-client-id>',
clientSecret: '<your-client-secret>',
afterSignInUrl: 'http://localhost:3000/login',
afterSignOutUrl: 'http://localhost:3000/logout',
}),
);
app.get('/', (_req, res) => {
res.send('<a href="/protected">Go to protected page</a>');
});
app.get('/login', handleSignIn());
app.get('/logout', handleSignOut());
app.get(
'/protected',
protect((res) => res.redirect('/login')),
(_req, res) => {
res.send('You are signed in and can access this protected route.');
},
);
app.get('/me', protect(), async (req, res) => {
const user = await req.thunderIDAuth.getUserFromRequest(req);
res.json(user);
});
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
Flow Lifecycle
- The user opens a protected route.
protect()checks the session cookie and current sign-in state.- If the request is unauthenticated, your
onUnauthenticatedcallback can redirect to/login. handleSignIn()starts the redirect flow.- ThunderID redirects back to the configured sign-in callback route.
handleSignIn()exchanges the authorization code for tokens and sets the session cookie.- Protected routes can now continue and route handlers can read the signed-in user.
Access the Current User
After thunderID() runs, the initialized client is available on req.thunderIDAuth.
index.js
app.get('/me', protect(), async (req, res) => {
const user = await req.thunderIDAuth.getUserFromRequest(req);
res.json(user);
});