具有 Express 会话问题的节点

我使用以下有效的代码,但是在几次成功调用(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它只是一个快速服务器):


索引.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}`));

有时当我调试时,我看到函数正在运行,GetUsers这是一个异步函数并停止在 中})(req, res, next);,可能是异步问题。

我们想在 prod 中使用这段代码,而不是以前的 Java 实现。

如果我可以对 oidc 使用另一种技术,请告诉我。


阿晨1998
浏览 198回答 4
4回答

米脂

这个问题似乎是一个竞争条件,如果你碰巧同时收到两个请求,在飞行中,当一个请求完成时,它会在另一个有机会完成之前清除会话 cookie。不管怎样,您不是唯一遇到此问题的人。不过,我认为这不是库本身的问题,我认为问题更多在于会话库。您可能想尝试将/选项设置为express-session的库,并检查您是否仍然看到相同的问题,例如saveUninitializedresavefalseconst session = require('express-session');...app.use(session({  saveUninitialized: false,  resave: false});cookie-session此库与您使用的库之间的唯一区别是express-session仅将会话 ID 存储在 cookie 中,数据存储在服务器端。如果您发现它有效,那么您可以考虑使用更具生产级的商店(默认设置是使用内存中的商店运行)。FWIW - 你只需要配置一次策略,看看它做了什么,如果它是问题的一部分我会感到惊讶但我会修复它以防万一

FFIVE

我们遇到了类似的问题,但我们有更多的间歇性行为,我们在 Safari 上登录时出现错误,但在 Chrome 上却没有。据我了解,这是因为会话 cookie 在我们第一次进行身份验证时被设置,它存储state, code-verifier(仅当使用 PKCE 流时)和 OIDC 客户端验证身份验证所需的其他值。但是,当 /callback URL 被命中时,浏览器会将此会话 cookie 发送到服务器以完成身份验证。每当未发送此 cookie 时,就会发生此错误,因为回调假定这是一个新请求并且它崩溃了......对我们来说,这有两种表现方式。Cookie { 同一站点:'Lax' 安全:true }适用于 chrome,但这不适用于 safariCookie { 同一站点:'无' 安全:true }适用于 chrome 和 safari这需要在 express-session 中间件上设置(抱歉,我不确定所需的语法)

桃花长相依

一种想法是,如果您决定启用会话,那么您需要在 passport.session() 之前使用 express.session() 以确保以正确的顺序恢复用户的登录会话。看这篇文章

波斯汪

使用瀑布异步功能可能对此有所帮助。只需将 app.get 路由功能替换为以下代码即可。当我们必须运行依赖于前一个任务的输出的任务时,Waterfall 会很有帮助。    app.get('/redirect', async (req, res, next) => {        await passport.authenticate('oidc',            async.waterfall([                function (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);                        }                    });                }            ], function (err) {                if (err) return next(err);  //here you can check error            })           );    });
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript