Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@okta/oidc-middleware
Advanced tools
This package makes it easy to get your users logged in with Okta using OpenId Connect (OIDC). It enables your Express application to participate in the authorization code flow flow by redirecting the user to Okta for authentication and handling the callback from Okta. Once this flow is complete, a local session is created and the user context is saved for the duration of the session.
npm install --save @okta/oidc-middleware
ExpressOIDC
. By default, the session middleware uses a MemoryStore, which is not designed for production use. Use another session store for production.Below is a terse Express application that examples the basic usage of this library. If you'd like to clone a complete example, please see the Okta Express Samples Repository.
const express = require('express');
const session = require('express-session');
const { ExpressOIDC } = require('@okta/oidc-middleware');
const app = express();
const oidc = new ExpressOIDC({
issuer: 'https://{yourOktaDomain}.com/oauth2/default',
client_id: 'XXXXX',
client_secret: 'XXXXX',
redirect_uri: 'http://localhost:3000/authorization-code/callback',
scope: 'openid profile'
});
app.use(session({
secret: 'this-should-be-very-random',
resave: true,
saveUninitialized: false
}));
app.use(oidc.router);
app.get('/', (req, res) => {
if (req.userinfo) {
res.send(`Hello ${req.userinfo.name}! <a href="logout">Logout</a>`);
} else {
res.send('Please <a href="/login">login</a>');
}
});
app.get('/protected', oidc.ensureAuthenticated(), (req, res) => {
res.send('Top Secret');
});
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
oidc.on('ready', () => {
app.listen(3000, () => console.log('app started'));
});
oidc.on('error', err => {
// An error occurred while setting up OIDC
});
To configure your OIDC integration, create an instance of ExpressOIDC
and pass options. Most apps will need this basic configuration:
const { ExpressOIDC } = require('@okta/oidc-middleware');
const oidc = new ExpressOIDC({
issuer: YOUR_ISSUER,
client_id: YOUR_CLIENT_ID,
client_secret: YOUR_CLIENT_SECRET,
redirect_uri: YOUR_REDIRECT_URI,
scope: 'openid profile'
});
Required config:
https://YOUR_ORG.oktapreview.com/oauth2/default
)http://localhost:3000/authorization-code/callback
. When deployed, this should be https://YOUR_PROD_DOMAIN/authorization-code/callback
.Optional config:
code
openid
, which will only return the sub
claim. To obtain more information about the user, use openid profile
. For a list of scopes and claims, please see Scope-dependent claims for more information.This should be added to your express app to attach the login and callback routes:
const { ExpressOIDC } = require('@okta/oidc-middleware');
const express = require('express');
const app = express();
const oidc = new ExpressOIDC({ /* options */ });
app.use(oidc.router);
It's required in order for ensureAuthenticated
and isAuthenticated
to work and adds the following routes:
/login
- redirects to the Okta sign-in page by default/authorization-code/callback
- processes the OIDC response, then attaches userinfo to the sessionThe middleware must retrieve some information about your client before starting the server. You must wait until ExpressOIDC is ready to start your server.
oidc.on('ready', () => {
app.listen(3000, () => console.log('app started'));
});
This is triggered if an error occurs while ExpressOIDC is trying to start.
oidc.on('error', err => {
// An error occurred while setting up OIDC
});
Use this to protect your routes. If not authenticated, this will redirect to the login route and trigger the authentication flow. If the request prefers JSON then a 401 error response will be sent.
app.get('/protected', oidc.ensureAuthenticated(), (req, res) => {
res.send('Protected stuff');
});
The redirectTo
option can be used to redirect the user to a specific URI on your site, after a successful authentication callback.
This allows you to determine if a user is authenticated.
app.get('/', (req, res) => {
if (req.isAuthenticated()) {
res.send('Logged in');
} else {
res.send('Not logged in');
}
});
This allows you to end the session.
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
This provides information about the authenticated user, and is obtained from the userinfo endpoint of the authorization server and depends on the scope requested (see scope option above):
app.get('/', (req, res) => {
if (req.userinfo) {
res.send(`Hi ${req.userinfo.sub}!`);
} else {
res.send('Hi!');
}
});
If you need to modify the default login and callback routes, the routes
config option is available.
const oidc = new ExpressOIDC({
// ...
routes: {
login: {
path: '/different/login'
},
callback: {
path: '/different/callback',
handler: (req, res, next) => {
// Perform custom logic before final redirect, then call next()
},
defaultRedirect: '/home'
}
}
});
callback.defaultRedirect
- Where the user is redirected to after a successful authentication callback, if no returnTo
value was specified by oidc.ensureAuthenticated()
. Defaults to /
.callback.handler
- A function that is called after a successful authentication callback, but before the final redirect within your application. Useful for requirements such as conditional post-authentication redirects, or sending data to logging systems.callback.path
- The URI that this library will host the callback handler on. Defaults to /authorization-code/callback
login.path
- The URI that redirects the user to the authorize endpoint. Defaults to /login
.By default the end-user will be redirected to the Okta Sign-In Page when authentication is required, this page is hosted on your Okta Org domain. It is possible to host this experience within your own application by installing the Okta Sign-In Widget into a page in your application. Please refer to the test example file for an example of how the widget should be configured for this use case.
Once you have created your login page, you can use the viewHandler
option to intercept the login page request and render your own custom page:
const oidc = new ExpressOIDC({
{ /* options */ }
routes: {
login: {
viewHandler: (req, res, next) => {
const baseUrl = url.parse(baseConfig.issuer).protocol + '//' + url.parse(baseConfig.issuer).host;
// Render your custom login page, you must create this view for your application and use the Okta Sign-In Widget
res.render('login', {
csrfToken: req.csrfToken(),
baseUrl: baseUrl
});
}
}
}
});
To add additional data about a user from your database, we recommend adding middleware to extend req
.
const { ExpressOIDC } = require('@okta/oidc-middleware');
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({ /* options */ }));
const oidc = new ExpressOIDC({ /* options */ });
app.use(oidc.router);
function addUserContext(req, res, next) {
if (!req.userinfo) return next();
// request additional info from your database
User.findOne({ id: req.userinfo.sub }, (err, user) => {
if (err) return next(err);
req.user = user;
next();
});
}
app.use(addUserContext);
{ /* options */ } // add other routes
oidc.on('ready', () => app.listen(3000));
oidc.on('error', err => console.log('could not start', err));
FAQs
OpenId Connect middleware for authorization code flows
We found that @okta/oidc-middleware demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.