I use the this library to use oidc
with nodejs
What I need is the following:
user login with user password, or have the data already the session cookie. this is calling to my app root route "/"
I've registered the application already in the authorization server
, the auth server should call to my the app/redirect
from the auth server I took the clientId and client secret and put it in the app.
When the user logged-in the auth server should call to my application redirect route .
From the oidc
strategy I need to get the tokenset.claims();
and from it tokenset.id_token
, the user token. , in the redirect call
It should be with
response_type: 'code',
https://github.com/auth0/express-openid-connect#getting-started
The problem is the getUser
function is called (while debug the application) however I got the userIdentity
from req.session.userIdentity
which is undefined
, any idea what could be wrong here?
We are having the same old implementation which using OIDC and it works for the same auth server and clientid and secret.
const { auth, requiresAuth } = require('express-openid-connect');
const session = require('express-session');
const bodyParser = require('body-parser');
module.exports = async (app) => {
const ClientId = process.env.CI;
const ClientSecret = process.env.CS;
const URL = process.env.S_URL;
app.use(session({
name: 'bat-auth',
secret: 'cookie-secret',
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(auth({
clientSecret: ClientSecret,
issuerBaseURL: `${URL}`,
clientID: ClientId,
baseURL: process.env.REDT_URL,
redirectUriPath: '/redirect', //my app redirect route
authorizationParams: {
response_type: 'code',
response_mode: 'form_post',
scope: 'openid',
},
async handleCallback(req, res, next) {
req.session.openidTokens = req.openidTokens;
console.log('---req.openidTokens', req.openidTokens);
req.session.userIdentity = req.openidTokens.claims();
next();
},
async getUser(req) {
return req.session.userIdentity;
},
}));
app.get('/', (req, res) => {
const tokenSet = req.openid.makeTokenSet(req.session.openidTokens);
console.log(`tokenset root: ${tokenSet}`);
res.send(req.isAuthenticated() ? 'Logged in' : 'Logged out');
});
app.get('/redirect', async (req, res) => {
const tokenSet = req.openid.makeTokenSet(req.session.openidTokens);
console.log(`tokenset: ${tokenSet}`);
console.log('redirect called');
res.send('redirect called');
});
I should use form post and at the end, what I need is to get from the tokenset
, user.id_token
?
This is what I've, and verified!
- ClientID from auth server
- ClientSecret from auth server
- Config the auth server my app
redirect
path, which should called me after successful login- I've also the
aud
key
Btw, while debug the application it doesn't stops add handleCallback function , but it stops on the getUser
app first, not sure what could be the reason...
It looks like you're trying to read from req.session.userIdentity
but you never set it anywhere. You're setting req.session.openidTokens
instead.
Based on the example code, you probably want to modify your handleCallback function to the following:
async handleCallback(req, res, next){
req.session.openidTokens = req.openidTokens;
console.log('---req.openidTokens', req.openidTokens);
req.session.userIdentity = req.openidTokens.claims(); // <-- this is required to make your code sample work
next();
}
A few points from looking at what you've done. You have not made it too easy for people to answer your question, and there is more you can do to improve your own self diagnosis:
RESPONSE MODE
Get rid of this field - I think I'm right in saying this should always be set to 'query' for the Authorization Response and that will be the default value. It is possible that is causing problems.
ASYNC SYNTAX
I could be wrong, but I would start with the exact syntax from the Auth0 page. Sometimes I've made mistakes in this area via the wrong syntax.
handleCallback: async function (req, res, next) {
req.session.userIdentity = req.openidTokens.claims();
next();
},
HTTP DEBUGGING
Tore is 100% right in saying you should trace messages and post any failures here. As an example of how messages should look, see my blog post. This covers the client side Authorization Code Flow (PKCE) rather than the server side Authorization Code Flow, but the messages are very similar.
The wider point here is that if you do not gain an understanding of OAuth messages and token fields, you will be frequently blocked, rather than being able to diagnose your own problems. In your case, perhaps step 7 is not coming back as the expected query parameter and the library is failing as a result?
HOW TO CAPTURE HTTP MESSAGES
Can you update your config along the same lines as my NodeJS API by adding the following type of configuration, then running a tool such as Fiddler or Charles. You should then be able to capture OAuth messages between your web back end and the Authorization Server, then post any failing ones back here:
auth({
client_id: 'qhuefhuef',
...,
httpOptions: {
agent: TunnelAgent.httpsOverHttp({
proxy: Url.parse('http://127.0.0.1:8888'),
})
}
It is well worth taking a bit of time out to get this working, and will benefit all future development in this area. Some further details in my HTTP debugging write up.
ERROR HANDLING
Another possibility is that the Authorization Server is returning an error response in the standard 'error' / 'error_description' fields and you are not handling them.
Don't be satisfied once you've solved your immediate problem. There are multiple moving parts to OAuth solutions, and intermittent problems happen, which you will want to be able to resolve quickly once you deploy your app to testers or production.
I always recommend making OAuth messages fail during the development process, then ensuring that you are capturing the right data and in control of UI error reporting. See steps 10 and 17 of my write up for an approach to testing the points of failure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With