Node authentication with Passport.js and OpenID Connect
This post demonstrates how to set up OpenID Connect authentication in Node with Passport.js.
Node authentication with Passport.js and OpenID Connect
This post demonstrates how to set up OpenID Connect authentication in Node with Passport.js.
sachin saxena
If I need the access token returned after authentication, how can I get that ?
Randall Degges
When you first create the passport strategy, there’s a callback function that in the example above isn’t using, eg:
// set up passport
passport.use(‘oidc’, new OidcStrategy({
issuer: ‘https://dev-846291.oktapreview.com/oauth2/default’,
authorizationURL: ‘https://dev-846291.oktapreview.com/oauth2/default/v1/authorize’,
tokenURL: ‘https://dev-846291.oktapreview.com/oauth2/default/v1/token’,
userInfoURL: ‘https://dev-846291.oktapreview.com/oauth2/default/v1/userinfo’,
clientID: ‘{ClientID}’,
clientSecret: ‘{ClientSecret}’,
callbackURL: ‘http://localhost:3000/authorization-code/callback’,
scope: ‘openid profile’
}, (issuer, sub, profile, accessToken, refreshToken, done) => {
return done(null, profile);
}));
What you can do is take the accessToken
variable from there and store it someplace for later usage =)
Brian McBride
I’m always looking for more articles on how people implemented passport and Okta is a great product.
it might be great to see an example with Okta using JWTs & Authentication Headers over cookies. When I saw express-session there, I had to check the date of this blog post as I was thinking I might be seeing something from a couple years ago
Sathish Balasubramaniyan
How can I get the OIDC ID Token if I need it?
Randall Degges
I believe it’s in the session cookie already.
Adam
Thanks for the article! Got me on the right path, but the passport-openidconnect package did not work for other oidc provider implementations like IdentityServer4. The auth redirect url is not formed correctly, so the provider rejects the request. There are a number of parameters missing such as a nonce value. I was able to use the following package’s strategy and it worked like a champ. https://github.com/panva/no…
Joao Reis
should the secret be hardcoded? seems like a security flaw to me…
Lee Brandt
Never. This is just for demonstration purposes. Secrets can be stored and used in lots of secure ways. This is more about demonstrating how passport works with OIDC,
Vadym Rybak
no, you can find ID Token in params object which is missing in example callback above:
(issuer, sub, profile, accessToken, refreshToken, params, done)
Vishnu Karthik Reddy Aleti
Hi Team, Thank you for this great article. In my case, we have Loopback framework with Node.Js. So, how shall i implement this Okta with my application. This article is purely for NodeJs & ExpressJs. kindly advise me. Thank you in advance.
pragmaticivan
FYI, req.session.destroy()
performs race condition. express-session only performs .save
on res.end
, it doesn’t wait for redirects.
If you are connected to a store that has some latency, it will redirect before it destroys the session.
Greg Steven
Is this the recommended approach, or is using @okta/oidc-middleware, as described in https://developer.okta.com/…, the standard approach?
leebrandt
The Okta oidc-middleware is probably the more common approach. But if your developers are already familiar with setting up and configuring Passport for authentication, then that might be the right approach for your organization.
Roman Soulman
Thank you for the article, @leebrandt ! Any reason you picked ‘passport-openidconnect’ vs. ‘openid-client’ (http://www.passportjs.org/p… - an OIDC client despite the name) which has many more downloads?
Frédéric Mériot
Hi,
personally, I preferred to use the official library openid-client. The one used in this example no longer seems to be maintained.
Nomi
Great article, got a question though. Where is the user? You have a login link which invokes login flow and calls call back method to redirect to a page printing user.displayName but which user? no user singed in yet. I am confused.
I’m stuck…
I followed this and other posts to add the ‘groups’ claim to the example app.
I verified in the Okta admin UI → Token preview, that I see the groups list.
But, the profile page does not list the groups claim. Nor does it appear in the ‘req.user’ object when I dump it to the console.
I was quite surprised to not be able to find a step-by-step that covers this.
Is there such a guide or post?
Otherwise can the steps to accomplish that be shared here?
Thanks.
Hi @Opher
I can think of a couple of quick things you can check, but if these don’t work let us know!
groups
claim is added to your access token or ID token, for debugging purposes you can enable it for to both token types.https://<your-okta-domain>/oauth2/<id>
, typically it would look like https://dev-133337.okta.com/oauth2/default
If that doesn’t help, can you include the data you are getting from req.user
(sanitize the data before posting).
Keep us posted!
Not sure if this topic is still active, but I am attempting to follow the original guide.
I have Passport configured as follows:
const oktaDomain = 'dev-XXXXXXXX.okta.com';
const clientID = 'XXXXXXXXXXXXXXX';
const issuer = `https://${oktaDomain}/oauth2/default`;
passport.use('oidc', new Strategy({
issuer,
authorizationURL: `https://${oktaDomain}/oauth2/default/v1/authorize`,
tokenURL: `https://${oktaDomain}/oauth2/default/v1/token`,
userInfoURL: `https://${oktaDomain}/oauth2/default/v1/userinfo`,
clientID: `${clientID}`,
callbackURL: 'http://localhost:3000/authorization-code/callback',
scope: 'openid profile'
}, (issuer, profile, done) => {
return done(null, profile);
}));
where callbackURL is equal to the Sign In Redirect URI I set for my SPA.
However, when I click the Log In link I get the following error:
PKCE code challenge is required by the application.
500
AuthorizationError: PKCE code challenge is required by the application.
at Strategy.authenticate (/home/rlowles/Documents/OktaTesting/okta-node-passport-oidc-example/node_modules/passport-openidconnect/lib/strategy.js:99:25)
[...]
Is there a step or setting in Okta that I missed which would be causing this error?