I have been following the guides (Sign users in to your web app using the redirect model | Okta Developer and Node authentication with Passport.js and OpenID Connect) for using nodejs and passport to handle user logins, and they just aren’t working. I always get a 404, which seems to be from the /error endpoint from the failureRedirect: /error config in the /pl/oidcallback endpoint.
The code is almost completely copy and pasted from those guides (the only major difference is my callback url), but I’m assuming something has changed in the 5 years since they were created that I’m missing.
From what I can gather, it seems like passport just isn’t doing anything once it receives the code on the callback, I can see both the code and the state in the get log, but nothing happens and it redirects to the /error endpoint.
app.use(session({
secret: 'MyVoiceIsMyPassportVerifyMe',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use('oidc', new Strategy({
issuer: 'https://{okta dev id}.okta.com/',
authorizationURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/authorize',
tokenURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/token',
userInfoURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/userinfo',
clientID: {id},
clientSecret: {secret},
callbackURL: 'http://localhost:3000/pl/oidcallback',
scope: 'openid profile'
}, (issuer, profile, done) => {
return done(null, profile);
}));
passport.serializeUser((user, next) => {
next(null, user);
});
passport.deserializeUser((obj, next) => {
next(null, obj);
});
...
app.use('/login', passport.authenticate('oidc'));
app.use('/pl/oidcallback',
passport.authenticate('oidc', { failureRedirect: '/error' }),
(req, res) => {
res.redirect('/profile');
}
);
function ensureLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login')
}
app.use('/profile', ensureLoggedIn, (req, res) => {
res.render('profile', { title: 'Express', user: req.user });
});
app.get('/logout', (req, res) => {
req.logout();
req.session.destroy();
res.redirect('/');
});
After adding failureMessage: true, failWithError: true and removing failureRedirect from the passport config, I get the following error as a response:
Forbidden
403
AuthenticationError: Forbidden
at allFailed (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:175:21)
at attempt (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:183:28)
at strategy.fail (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:305:9)
at okta-node-passport-oidc-example/node_modules/passport-openidconnect/lib/strategy.js:171:56
at okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:209:7
at passBackControl (okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:134:9)
at IncomingMessage.<anonymous> (okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:157:7)
at IncomingMessage.emit (node:events:526:35)
at endReadableNT (node:internal/streams/readable:1408:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)