I use the following code which works, However after a few success calls (5-10), we sometimes get an internal server error:
req.session["oidc:accounts.rvm.com"] is undefined
I've tried all the latest
open source versions.
Error: did not find expected authorization request details in session, req.session["oidc:accounts.rvm.com"] is undefined
at /opt/node_app/app/node_modules/openid-client/lib/passport_strategy.js:125:13
at OpenIDConnectStrategy.authenticate (/opt/node_app/app/node_modules/openid-client/lib/passport_strategy.js:173:5)
at attempt (/opt/node_app/app/node_modules/passport/lib/middleware/authenticate.js:366:16)
at authenticate (/opt/node_app/app/node_modules/passport/lib/middleware/authenticate.js:367:7)
at /opt/node_app/app/src/logon.js:92:7 *******
at Layer.handle [as handle_request] (/opt/node_app/app/node_modules/express/lib/router/layer.js:95:5)
at next (/opt/node_app/app/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/opt/node_app/app/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/opt/node_app/app/node_modules/express/lib/router/layer.js:95:5)
at /opt/node_app/app/node_modules/express/lib/router/index.js:281:22
My code from the stack is:
at /opt/node_app/app/src/logon.js:92:7
Which is the end of the code here:
})(req, res, next); // here is line 92 but not sure if it's related
This is the full code (I pass the app
which is simply an express server):
index.js
const express = require('express');
const logon = require('./logon');
const app = express();
const port = process.env.PORT || 4000;
logon(app)
.then(() => {
console.log('process started');
});
app.use(express.json());
app.listen(port,
() => console.log(`listening on port: ${port}`));
logon.js
const { Issuer, Strategy } = require('openid-client');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
const azpi = require('./azpi');
const bodyParser = require('body-parser');
const passport = require('passport');
module.exports = async (app) => {
let oSrv;
const durl = `${process.env.srvurl}/.well-known/openid-configuration`;
try {
oSrv = await Issuer.discover(durl);
} catch (err) {
console.log('error occured', err);
return;
}
app.get('/', prs(), passport.authenticate('oidc'));
const oSrvCli = new oSrv.Client({
client_id: process.env.ci,
client_secret: process.env.cs,
token_endpoint_auth_method: 'client_secret_basic',
});
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
const cfg = {
scope: 'openid',
redirect_uri: process.env.ruri,
response_type: 'code',
response_mode: 'form_post',
};
const prs = () => (req, res, next) => {
passport.use(
'oidc',
new Strategy({ oSrvCli , cfg }, (tokenset, done) => {
const claims = tokenset.claims();
// first log
console.log(`1. ------------User claims received------------);
const user = {
name: claims.name,
id: claims.sub,
id_token: tokenset.id_token,
};
return done(null, user);
}),
);
next();
};
app.use(
bodyParser.urlencoded({
extended: false,
}),
);
app.use(cookieParser('csec'));
app.use(
cookieSession({
name: 'zta-auth',
secret: 'csect',
}),
);
app.use(passport.initialize());
app.use(passport.session());
app.get('/redirect', async (req, res, next) => {
await passport.authenticate('oidc', async (err, user) => {
// print second log
console.log('2. ------------redirect Called!------------');
if (err) {
console.log(`Authentication failed: ${err}`);
return next(err);
}
if (!user) {
return res.send('no identity');
}
req.login(user, async (e) => {
if (e) {
console.log('not able to login', e);
return next(e);
}
try {
const url = await azpi.GetUsers(user.id_token);
// print last log
console.log('3. ------------user process finished successfully----');
return res.redirect(url);
} catch (er) {
res.send(er.message);
}
});
})(req, res, next); //here is the error
});
};
Sometimes when I debug, I see that the function is running out from GetUsers
which is an async function and stops in })(req, res, next);
, maybe it's an async issue.
We want to use this code in prod instead of the previous Java implementation.
If I can use another technique for oidc, please let me know.
UPDATE
Each should be a single call and log in this order:
1. ------------User claims received------------
2. ------------redirect Called!------------
3. ------------user process finished successfully----
But, when I get the error:
1. ------------User claims received------------
2. ------------redirect Called!------------
3. ------------user process finished successfully----
2. ------------redirect Called!------------
Authentication failed: Error: did not find expected authorization request details in session, req.session
All the successful calls have the right log order (1-3).
When it fails, the first call User claims received
doesn't happen, just the second and the error.
If there is another way to achieve this (other lib's etc), please let me know.
I've found this library which may help as it doesn't use passport (I want to reduce deps to see where the problem is coming from).
When I try something like this:
app.use(
auth({
issuerBaseURL: `${URL}/.well-known/openid-configuration`,
authorizationParams: {
...
response_mode: 'form_post',
}
I get this error: issuer response_mode supporting only "query" or "fragment"
, but when I run the code above (in the beginning of the post) with the same issuer
and response_mode
, everything is working, any ideas?
We faced a similar issue but we had a more intermittent behavior, we had the error when logging in on Safari but not on Chrome.
From what I understood, this is because the session cookie is getting set when we are first authenticating, which stores the state
, code-verifier
(only if using PKCE flow) and other values the OIDC client needs to validate the authentication.
However, when the /callback URL is hit, the browser sends this session cookie to the server to complete authentication.
Whenever this cookie is not sent, thats when this error occurs, because the callback assumes this to be a new request and it crashes...
for us this was behaving in 2 ways.
Cookie { Same-site: 'Lax' secure: true }
Works for chrome but this did not work on safari
Cookie { Same-site: 'None' secure: true }
Works for chrome and on safari
this needs to be set on the express-session middleware (sorry Im not sure of the syntax thats needed)
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