【发布时间】:2020-11-25 06:37:26
【问题描述】:
我使用以下代码有效,但是在几次成功调用(5-10)之后,我们有时会收到内部服务器错误:
req.session["oidc:accounts.rvm.com"] is undefined
我已经尝试了所有latest 开源版本。
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
我的堆栈代码是:
at /opt/node_app/app/src/logon.js:92:7
这里的代码结束了:
})(req, res, next); // here is line 92 but not sure if it's related
这是完整的代码(我传递了app,它只是一个快速服务器):
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
});
};
有时当我调试时,我看到函数从 GetUsers 用尽,这是一个异步函数并在 })(req, res, next); 停止,可能是异步问题。
我们想在 prod 中使用这段代码,而不是之前的 Java 实现。
如果我可以对 oidc 使用其他技术,请告诉我。
更新
每个都应该是一个单独的调用并按以下顺序登录:
1. ------------User claims received------------
2. ------------redirect Called!------------
3. ------------user process finished successfully----
但是,当我收到 错误 时:
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
所有成功的调用都有正确的日志顺序(1-3)。
当它失败时,第一次调用User claims received 不会发生,只会发生第二次和错误。
如果有其他方法可以实现这一点(其他库等),请告诉我。
我发现 this 库可能会有所帮助,因为它不使用护照(我想减少部门以查看问题出在哪里)。
当我尝试这样的事情时:
app.use(
auth({
issuerBaseURL: `${URL}/.well-known/openid-configuration`,
authorizationParams: {
...
response_mode: 'form_post',
}
我收到此错误:issuer response_mode supporting only "query" or "fragment",但是当我使用相同的 issuer 和 response_mode 运行上面的代码(在帖子的开头)时,一切正常,有什么想法吗?
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
-
一个严重的问题:你在定义函数之前调用
prs(),这会引发异常。 -
我也不知道护照,但是你会在每个请求的中间件中创建一个
new Strategy看起来很奇怪,尽管它似乎独立于req和@ 987654344@。我会假设passport.use(…)应该只被调用一次。 -
@Bergi - 谢谢,
prs()我已经更改了它并得到了相同的结果,关于护照使用不确定如何更改我的代码,您能否提供一个示例作为答案我试试看? -
@James But still cause an exception
标签: javascript node.js async-await passport.js openid-connect