### Basic Middleware Setup with requiresAuth Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of setting up the auth middleware and using the requiresAuth guard for a specific route. ```javascript const { auth, requiresAuth } = require('express-openid-connect'); app.use(auth(config)); app.get('/admin', requiresAuth(), (req, res) => { res.send('Admin page'); }); ``` -------------------------------- ### Example Environment Configuration Source: https://github.com/auth0/express-openid-connect/blob/master/examples/README.md Configure these environment variables to run the example app against your authorization server. If no .env file is specified, a mock server will be started. ```shell # For the example app PORT=3000 # For the auth config ISSUER_BASE_URL=https://YOUR_DOMAIN CLIENT_ID=YOUR_CLIENT_ID BASE_URL=https://YOUR_APPLICATION_ROOT_URL SECRET=LONG_RANDOM_VALUE # For response_type values that include 'code' CLIENT_SECRET=YOUR_CLIENT_SECRET ``` -------------------------------- ### Basic Setup - Environment Variables Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Environment variables required for basic setup of the express-openid-connect middleware. ```text # .env ISSUER_BASE_URL=https://YOUR_DOMAIN CLIENT_ID=YOUR_CLIENT_ID BASE_URL=https://YOUR_APPLICATION_ROOT_URL SECRET=LONG_RANDOM_STRING ``` -------------------------------- ### Basic Setup - Express App Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md A minimal Express.js application demonstrating the basic setup of express-openid-connect, where all routes are protected by default. ```javascript // basic.js const express = require('express'); const { auth } = require('express-openid-connect'); const app = express(); app.use(auth()); app.get('/', (req, res) => { res.send(`hello ${req.oidc.user.sub}`); }); ``` -------------------------------- ### Client Authentication Methods Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Examples of how to configure different client authentication methods. ```javascript app.use(auth({ clientAuthMethod: 'client_secret_basic' })); app.use(auth({ clientAuthMethod: 'client_secret_post' })); app.use(auth({ clientAuthMethod: 'client_secret_jwt' })); app.use(auth({ clientAuthMethod: 'private_key_jwt' })); app.use(auth({ clientAuthMethod: 'none' })); ``` -------------------------------- ### Run an Example Source: https://github.com/auth0/express-openid-connect/blob/master/examples/README.md Use this command to run a specific example by its name. For instance, to run the basic example located at `./basic.js`, use 'basic'. ```shell npm run start:example -- basic ``` -------------------------------- ### HTTP Agent Configuration (v3) Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of using customFetch with ProxyAgent in v3. ```javascript const { ProxyAgent, fetch: undiciFetch } = require('undici'); const dispatcher = new ProxyAgent('http://proxy.example.com:8080'); app.use( auth({ customFetch: (url, options) => undiciFetch(url, { ...options, dispatcher }), }), ); ``` -------------------------------- ### HTTP Agent Configuration (v2) Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of using httpAgent with ProxyAgent in v2. ```javascript const { ProxyAgent } = require('proxy-agent'); app.use( auth({ httpAgent: new ProxyAgent('http://proxy.example.com:8080'), }), ); ``` -------------------------------- ### Session Configuration Options Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of configuring session options, including rolling duration and custom stores. ```javascript app.use( auth({ session: { rolling: true, rollingDuration: 86400, absoluteDuration: 86400 * 7, store: customStore, }, }), ); ``` -------------------------------- ### Standard express-openid-connect Configuration Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of a typical configuration object for the express-openid-connect middleware. ```javascript app.use( auth({ authRequired: false, auth0Logout: true, baseURL: 'https://example.com', clientID: 'YOUR_CLIENT_ID', issuerBaseURL: 'https://YOUR_DOMAIN', secret: 'LONG_RANDOM_STRING', idpLogout: true, idTokenSigningAlg: 'RS256', clientAuthMethod: 'client_secret_post', pushedAuthorizationRequests: true, // ... all other options }), ); ``` -------------------------------- ### Accessing User Information and OIDC Methods Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example demonstrating how to access user data and OIDC-related methods from the req.oidc object. ```javascript app.get('/profile', async (req, res) => { const user = req.oidc.user; const claims = req.oidc.idTokenClaims; const isAuthenticated = req.oidc.isAuthenticated(); const idToken = req.oidc.idToken; const accessToken = req.oidc.accessToken; const refreshToken = req.oidc.refreshToken; const userInfo = await req.oidc.fetchUserInfo(); res.oidc.login({}); res.oidc.logout({}); }); ``` -------------------------------- ### Customizing Authentication Routes Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of configuring custom paths for login, logout, and callback routes. ```javascript app.use( auth({ routes: { login: '/custom/login', logout: '/custom/logout', callback: '/custom/callback', postLogoutRedirect: '/custom/post-logout', }, }), ); ``` -------------------------------- ### clientAssertionSigningAlg Config Now Required Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example showing the change in requirement for clientAssertionSigningAlg when clientAssertionSigningKey is a PEM string. ```javascript app.use( auth({ clientAssertionSigningKey: '-----BEGIN PRIVATE KEY-----\n...', // clientAssertionSigningAlg was optional, defaulted to RS256 }), ); ``` ```javascript app.use( auth({ clientAssertionSigningKey: '-----BEGIN PRIVATE KEY-----\n...', clientAssertionSigningAlg: 'RS256', // now required for PEM keys }), ); ``` -------------------------------- ### Install express-openid-connect Source: https://github.com/auth0/express-openid-connect/blob/master/README.md Install the library using npm. ```bash npm install express-openid-connect ``` -------------------------------- ### Calling userinfo Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example demonstrates how to call the /userinfo endpoint using the fetchUserInfo method available on the request context. ```javascript app.use(auth()); app.get('/', async (req, res) => { const userInfo = await req.oidc.fetchUserInfo(); // ... }); ``` -------------------------------- ### ES256K and EdDSA Removed Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example showing the removal of 'EdDSA' and 'ES256K' as accepted values for clientAssertionSigningAlg. ```javascript app.use( auth({ clientAssertionSigningAlg: 'EdDSA', }), ); ``` ```javascript app.use( auth({ clientAssertionSigningAlg: 'Ed25519', }), ); ``` -------------------------------- ### Example Usage Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/RequestContext.html Example of how to access user information from the request context. ```javascript app.use(auth()); app.get('/profile', (req, res) => { const user = req.oidc.user; ... ``` -------------------------------- ### Back-Channel Logout - Basic Configuration Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example configures the SDK for back-channel logout, enabling the `idpLogout` option and providing a session store for managing logout tokens. It creates a `/backchannel-logout` handler. ```javascript // index.js const { auth } = require('express-openid-connect'); const { createClient } = require('redis'); const RedisStore = require('connect-redis')(auth); // redis@v4 let redisClient = createClient({ legacyMode: true }); redisClient.connect(); app.use( auth({ idpLogout: true, backchannelLogout: { store: new RedisStore({ client: redisClient }), }, }), ); ``` -------------------------------- ### Fetch User Info Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/RequestContext.html Example of how to fetch the OIDC userinfo response using `fetchUserInfo()`. ```typescript app.use(auth()); app.get('/user-info', async (req, res) => { const userInfo = await req.oidc.fetchUserInfo(); res.json(userInfo); }) ``` -------------------------------- ### Example Usage Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ResponseContext.html Example of how to use the OpenID Connect auth middleware with Express. ```typescript app.use(auth()); app.get('/admin-login', (req, res) => { res.oidc.login({ returnTo: '/admin' }) }) ``` -------------------------------- ### afterCallback Behavior Change - After (v3) Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of the 'afterCallback' function in v3, demonstrating how to capture previous session state when the built-in callback route is disabled. ```javascript app.use( auth({ routes: { callback: false }, // disable the built-in /callback route async afterCallback(req, res, session) { // req.oidc.user is now the INCOMING user (new tokens) // use res.locals.previousUser for the prior state const previousUser = res.locals.previousUser; return session; }, }), ); // req.oidc is available here — auth() has already run its session setup for this request app.get('/callback', (req, res) => { res.locals.previousUser = req.oidc.user; // capture the previous session before it is replaced res.oidc.callback(); // proceed with OIDC callback processing }); ``` -------------------------------- ### Use a custom session store Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example shows how to use a custom session store, such as Redis, when the default encrypted cookie session becomes too large. It requires `connect-redis` and a Redis client. ```javascript const { auth } = require('express-openid-connect'); const { createClient } = require('redis'); const RedisStore = require('connect-redis')(auth); // redis@v4 let redisClient = createClient({ legacyMode: true }); redisClient.connect().catch(console.error); // redis@v3 let redisClient = createClient(); app.use( auth({ session: { store: new RedisStore({ client: redisClient }), }, }), ); ``` -------------------------------- ### Custom Token Exchange Example Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Demonstrates how to swap an access token for one accepted by a different downstream service using `customTokenExchange()`. ```javascript const { auth, requiresAuth } = require('express-openid-connect'); const axios = require('axios'); app.use( auth({ authorizationParams: { response_type: 'code', // Token issued at login is scoped to the upstream API audience: 'https://api.example.com', scope: 'openid profile offline_access', }, }), ); app.get('/reports', requiresAuth(), async (req, res, next) => { try { // Exchange the session token for one accepted by the reporting service. // subject_token and subject_token_type are resolved automatically. const { access_token } = await req.oidc.customTokenExchange({ audience: 'https://reports.internal.example.com', scope: 'openid read:reports', }); const { data } = await axios.get( 'https://reports.internal.example.com/v1/summary', { headers: { Authorization: `Bearer ${access_token}` } }, ); res.json(data); } catch (err) { // Authorization server rejections surface as HTTP 400 and 401 // with err.error and err.error_description set next(err); } }); ``` -------------------------------- ### Example Usage Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/OpenidRequest.html Example of how to use the `oidc` context in a request handler. ```typescript app.use(auth());app.get('/profile', (req, res) => { const user = req.oidc.user; ...}) ``` -------------------------------- ### Proxy Configuration for OIDC Requests Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Example of configuring `customFetch` with `undici`'s `ProxyAgent` to route OIDC requests through a proxy. ```javascript const express = require('express'); const { auth } = require('express-openid-connect'); const { ProxyAgent, fetch: undiciFetch } = require('undici'); const app = express(); const dispatcher = new ProxyAgent('http://proxy.example.com:8080'); app.use( auth({ customFetch: (url, options) => undiciFetch(url, { ...options, dispatcher }), // ... other options }), ); ``` -------------------------------- ### afterCallback Behavior Change - Before (v2) Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example of the 'afterCallback' function in v2, where req.oidc reflected the previous session state. ```javascript app.use( auth({ async afterCallback(req, res, session) { // req.oidc.user was the PREVIOUS user (before this login) const previousUser = req.oidc.user; return session; }, }), ); ``` -------------------------------- ### Login Override Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ResponseContext.html Example of how to override or have other login routes with custom authorizationParams or returnTo. ```typescript app.get('/admin-login', (req, res) => { res.oidc.login({ returnTo: '/admin', authorizationParams: { scope: 'openid profile email admin:user', } }); }); ``` -------------------------------- ### Custom Fetch Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ConfigParams.html Example demonstrating how to configure a custom fetch function to use a proxy agent for OIDC HTTP requests. ```javascript const { ProxyAgent, fetch: undiciFetch } = require('undici'); const dispatcher = new ProxyAgent('http://proxy.example.com:8080'); app.use(auth({ customFetch: (url, options) => undiciFetch(url, { ...options, dispatcher }), // ... other options })); ``` -------------------------------- ### Back-Channel Logout - Reusing Existing Session Store Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example shows how to enable back-channel logout while reusing an existing session store configured for stateful sessions. ```javascript app.use( auth({ idpLogout: true, session: { store: new RedisStore({ client: redisClient }), }, backchannelLogout: true, }), ); ``` -------------------------------- ### Required and Optional Configuration Parameters Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ConfigParams.html Example of how to configure required and optional parameters using environment variables. ```bash # Required ISSUER_BASE_URL=https://YOUR_DOMAIN BASE_URL=https://YOUR_APPLICATION_ROOT_URL CLIENT_ID=YOUR_CLIENT_ID SECRET=LONG_RANDOM_VALUE # Not required CLIENT_SECRET=YOUR_CLIENT_SECRET ``` -------------------------------- ### Require Authentication for Specific Routes Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Example demonstrating how to configure express-openid-connect to protect specific routes while allowing others to be accessed anonymously. ```javascript const { auth, requiresAuth } = require('express-openid-connect'); app.use( auth({ authRequired: false, }), ); // Anyone can access the homepage app.get('/', (req, res) => { res.send('Admin Section'); }); // requiresAuth checks authentication. app.get('/admin', requiresAuth(), (req, res) => res.send(`Hello ${req.oidc.user.sub}, this is the admin section.`); ) ``` -------------------------------- ### Callback Override Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ResponseContext.html Example of how to override or have other callback routes with custom redirect URIs. ```typescript app.get('/callback', (req, res) => { res.oidc.callback({ redirectUri: 'https://example.com/callback' });}); ``` -------------------------------- ### Logout Override Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ResponseContext.html Example of how to override or have other logout routes with custom returnTo. ```typescript app.get('/admin-logout', (req, res) => { res.oidc.logout({ returnTo: '/admin-welcome' })}); ``` -------------------------------- ### getLoginState Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ConfigParams.html Example of a getLoginState function to return custom state values for res.oidc.login(). ```javascript app.use(auth({ ... getLoginState(req, options) { return { returnTo: options.returnTo || req.originalUrl, customState: 'foo' }; } })) ``` -------------------------------- ### Protect a route based on specific claims Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example shows how to protect routes based on specific user claims using helper functions like claimEquals, claimIncludes, and claimCheck. These functions allow for granular access control based on user attributes. ```javascript const { auth, claimEquals, claimIncludes, claimCheck, } = require('express-openid-connect'); app.use( auth({ authRequired: false, }), ); // claimEquals checks if a claim equals the given value app.get('/admin', claimEquals('isAdmin', true), (req, res) => res.send(`Hello ${req.oidc.user.sub}, this is the admin section.`); // claimIncludes checks if a claim includes all the given values app.get( '/sales-managers', claimIncludes('roles', 'sales', 'manager'), (req, res) => res.send(`Hello ${req.oidc.user.sub}, this is the sales managers section.`); // claimCheck takes a function that checks the claims and returns true to allow access app.get( '/payroll', claimCheck(({ isAdmin, roles }) => isAdmin || roles.includes('payroll')), (req, res) => res.send(`Hello ${req.oidc.user.sub}, this is the payroll section.`); ``` -------------------------------- ### attemptSilentLogin Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/functions/attemptSilentLogin.html Example of how to use the attemptSilentLogin middleware to attempt silent login without requiring authentication. ```javascript const { attemptSilentLogin } = require('express-openid-connect'); app.get('/', attemptSilentLogin(), (req, res) => { res.render('homepage', { isAuthenticated: req.isAuthenticated() // show a login or logout button }); }); ``` -------------------------------- ### Vendor-specific parameters for Token Exchange Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Shows how to pass vendor-specific parameters like organization or connection during a custom token exchange. ```javascript const { downstreamToken } = await req.oidc.customTokenExchange({ audience: 'https://downstream-api.example.com', scope: 'read:data', extra: { organization: 'org_abc123', connection: 'google-oauth2', }, }); ``` -------------------------------- ### Obtaining access tokens to call external APIs Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example demonstrates how to obtain an access token to call external APIs by adding 'code' to the response_type and configuring the audience and scope. The access token is then used in the Authorization header for API requests. ```javascript app.use( auth({ authorizationParams: { response_type: 'code', // This requires you to provide a client secret audience: 'https://api.example.com/products', scope: 'openid profile email read:products', }, }), ); app.get('/', async (req, res) => { let { token_type, access_token } = req.oidc.accessToken; const products = await request.get('https://api.example.com/products', { headers: { Authorization: `${token_type} ${access_token}`, }, }); res.send(`Products: ${products}`); }); ``` -------------------------------- ### Refresh Access Token Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/AccessToken.html Example demonstrating how to check if an access token has expired and refresh it if necessary. ```typescript let accessToken = req.oidc.accessToken; if (accessToken.isExpired()) { accessToken = await accessToken.refresh(); } ``` -------------------------------- ### Custom afterCallback Function Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ConfigParams.html Example demonstrating how to use the `afterCallback` function to fetch user profile information after successful authentication and merge it into the session. ```javascript app.use(auth({ ... afterCallback: async (req, res, session, decodedState) => { const userProfile = await request(`${issuerBaseURL}/userinfo`); return { ...session, userProfile // access using `req.appSession.userProfile` }; }})) ``` -------------------------------- ### Logout from Identity Provider Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example shows how to configure the middleware to log the user out of both the application session and the Identity Provider (IDP) session by setting 'idpLogout: true'. ```javascript const { auth } = require('express-openid-connect'); app.use( auth({ idpLogout: true, // auth0Logout: true // if using custom domain with Auth0 }), ); ``` -------------------------------- ### claimCheck usage example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/functions/claimCheck.html Example of how to use the claimCheck middleware to protect a route with a custom claim checking function. ```javascript const { claimCheck } = require('express-openid-connect'); app.get('/admin/community', claimCheck((req, claims) => { return claims.isAdmin && claims.roles.includes('community'); }), (req, res) => { res.send(...); }); ``` -------------------------------- ### claimEquals usage example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/functions/claimEquals.html Example of how to use the claimEquals middleware to protect a route based on a claim's value. ```javascript const { claimEquals } = require('express-openid-connect'); app.get('/admin', claimEquals('isAdmin', true), (req, res) => { res.send(...); }); ``` -------------------------------- ### claimIncludes Usage Example Source: https://github.com/auth0/express-openid-connect/blob/master/docs/functions/claimIncludes.html Example of how to use the claimIncludes middleware to protect a route, ensuring all specified values are present in a claim. ```javascript const { claimIncludes } = require('express-openid-connect'); app.get('/admin/delete', claimIncludes('roles', 'admin', 'superadmin'), (req, res) => { res.send(...); }); ``` -------------------------------- ### Route Customization - Middleware Configuration Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md Customizing the default login, logout, and callback routes by disabling them and providing custom paths. ```javascript app.use( auth({ routes: { // Override the default login route to use your own login route as shown below login: false, // Pass a custom path to redirect users to a different // path after logout. postLogoutRedirect: '/custom-logout', // Override the default callback route to use your own callback route as shown below callback: false, }, }), ); app.get('/login', (req, res) => res.oidc.login({ returnTo: '/profile', authorizationParams: { redirect_uri: 'http://localhost:3000/callback', }, }), ); app.get('/custom-logout', (req, res) => res.send('Bye!')); app.get('/callback', (req, res) => res.oidc.callback({ redirectUri: 'http://localhost:3000/callback', }), ); app.post('/callback', express.urlencoded({ extended: false }), (req, res) => res.oidc.callback({ redirectUri: 'http://localhost:3000/callback', }), ); module.exports = app; ``` -------------------------------- ### Validate Claims from an ID token before logging a user in Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example demonstrates how to use the `afterCallback` hook to validate claims from an ID token before logging a user in. It checks the `org_id` claim to ensure the token was issued to the correct Organization. ```javascript app.use( auth({ afterCallback: (req, res, session) => { const claims = jose.JWT.decode(session.id_token); // using jose library to decode JWT if (claims.org_id !== 'Required Organization') { throw new Error('User is not a part of the Required Organization'); } return session; }, }), ); ``` -------------------------------- ### Example Usage Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/OpenidResponse.html Demonstrates how to use the `auth` middleware and access the `oidc` context on the response object for login. ```typescript app.use(auth()); app.get('/login', (req, res) => { res.oidc.login(); }) ``` -------------------------------- ### Obtaining and using refresh tokens Source: https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md This example shows how to obtain and use refresh tokens. Refresh tokens are requested using the 'offline_access' scope. The code checks if an access token is expired and attempts to refresh it if necessary before making an API call. ```javascript app.use( auth({ authorizationParams: { response_type: 'code', // This requires you to provide a client secret audience: 'https://api.example.com/products', scope: 'openid profile email offline_access read:products', }, }), ); app.get('/', async (req, res) => { let { token_type, access_token, isExpired, refresh } = req.oidc.accessToken; if (isExpired()) { ({ access_token } = await refresh()); } const products = await request.get('https://api.example.com/products', { headers: { Authorization: `${token_type} ${access_token}`, }, }); res.send(`Products: ${products}`); }); ``` -------------------------------- ### Client Assertion Signing Key - KeyObject Source: https://github.com/auth0/express-openid-connect/blob/master/docs/interfaces/ConfigParams.html Example of providing a client assertion signing key using a Node.js KeyObject. ```typescript app.use(auth({ ... clientAssertionSigningKey: crypto.createPrivateKey({ key: '-----BEGIN PRIVATE KEY-----\nMIIEo...PgCaw\n-----END PRIVATE KEY-----' }),})) ``` -------------------------------- ### Session Cookie Dropped When Headers Are Sent Before res.end() - res.flushHeaders() example Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example demonstrating how res.flushHeaders() explicitly flushes headers early, leading to the session cookie being dropped in v3. ```javascript app.get('/sse', (req, res) => { res.flushHeaders(); // headers sent here — session cookie will be dropped res.end(); }); ``` -------------------------------- ### Session Cookie Dropped When Headers Are Sent Before res.end() - res.write() example Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example demonstrating how res.write() can cause headers to be sent early, leading to the session cookie being dropped in v3. ```javascript app.get('/stream', (req, res) => { res.write('first chunk'); // headers sent here — session cookie will be dropped res.end('done'); }); ``` -------------------------------- ### Session Cookie Dropped When Headers Are Sent Before res.end() - res.sendFile() example Source: https://github.com/auth0/express-openid-connect/blob/master/V3_MIGRATION_GUIDE.md Example demonstrating how res.sendFile() pipes a stream and flushes headers early, leading to the session cookie being dropped in v3. ```javascript app.get('/file', (req, res) => { res.sendFile('/path/to/file'); // headers sent here — session cookie will be dropped }); ``` -------------------------------- ### Run project tests Source: https://github.com/auth0/express-openid-connect/blob/master/CONTRIBUTING.md Execute unit and integration tests to verify changes before submitting a pull request. ```bash npm run test npm run test:end-to-end ``` -------------------------------- ### Configure the SDK in library initialization Source: https://github.com/auth0/express-openid-connect/blob/master/README.md Configure the SDK directly in the library initialization using JavaScript. ```javascript // index.js const { auth } = require('express-openid-connect'); app.use( auth({ issuerBaseURL: 'https://YOUR_DOMAIN', baseURL: 'https://YOUR_APPLICATION_ROOT_URL', clientID: 'YOUR_CLIENT_ID', secret: 'LONG_RANDOM_STRING', idpLogout: true, }), ); ``` -------------------------------- ### Customize Routes Source: https://github.com/auth0/express-openid-connect/blob/master/V2_MIGRATION_GUIDE.md Routes can now be enabled individually and paths customized using the routes configuration object. ```js // Before app.use( auth({ routes: true, loginPath: '/custom/login', logoutPath: '/custom/logout', redirectUriPath: '/custom/callback', postLogoutRedirectUri: '/custom/post-logout', }) ); // After app.use( auth({ routes: { login: '/custom/login', logout: '/custom/logout', callback: '/custom/callback', postLogoutRedirect: '/custom/post-logout', }, }) ); ``` -------------------------------- ### Configuring Unique Cookie Names and Paths for Multiple Apps Source: https://github.com/auth0/express-openid-connect/blob/master/FAQ.md This example demonstrates how to configure unique cookie names and scoped paths for two applications hosted on the same domain but mounted at different paths to prevent cookie collisions. ```javascript app.use( '/app1', auth({ baseURL: 'https://example.com/app1', session: { name: 'app1Session', cookie: { path: '/app1' }, }, transactionCookie: { name: 'app1_auth_verification' }, }), ); app.use( '/app2', auth({ baseURL: 'https://example.com/app2', session: { name: 'app2Session', cookie: { path: '/app2' }, }, transactionCookie: { name: 'app2_auth_verification' }, }), ); ``` -------------------------------- ### Configure Session Lifecycle Source: https://github.com/auth0/express-openid-connect/blob/master/V2_MIGRATION_GUIDE.md Session duration management now includes explicit rolling and absolute duration settings. ```js // Before app.use( auth({ appSession: { duration: 86400, // default 1 day in secs }, }) ); // After app.use( auth({ appSession: { rolling: true, rollingDuration: 86400, // default 1 day rolling duration in secs absoluteDuration: 86400 * 7, // default 7 days absolute duration in secs }, }) ); ```