为了账号安全,请及时绑定邮箱和手机立即绑定

具有 Express 会话问题的节点

具有 Express 会话问题的节点

阿晨1998 2022-12-22 09:42:19
我使用以下有效的代码,但是在几次成功调用(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 undefinedat /opt/node_app/app/node_modules/openid-client/lib/passport_strategy.js:125:13at 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它只是一个快速服务器):索引.jsconst 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 使用另一种技术,请告诉我。
查看完整描述

4 回答

?
米脂

TA贡献1836条经验 获得超3个赞

这个问题似乎是一个竞争条件,如果你碰巧同时收到两个请求,在飞行中,当一个请求完成时,它会在另一个有机会完成之前清除会话 cookie。不管怎样,您不是唯一遇到此问题的人。


不过,我认为这不是库本身的问题,我认为问题更多在于会话库。您可能想尝试将/选项设置为express-session的库,并检查您是否仍然看到相同的问题,例如saveUninitializedresavefalse


const session = require('express-session');

...

app.use(session({

  saveUninitialized: false,

  resave: false

});

cookie-session此库与您使用的库之间的唯一区别是express-session仅将会话 ID 存储在 cookie 中,数据存储在服务器端。如果您发现它有效,那么您可以考虑使用更具生产级的商店(默认设置是使用内存中的商店运行)。


FWIW - 你只需要配置一次策略,看看它做了什么,如果它是问题的一部分我会感到惊讶但我会修复它以防万一


查看完整回答
反对 回复 2022-12-22
?
FFIVE

TA贡献1797条经验 获得超6个赞

我们遇到了类似的问题,但我们有更多的间歇性行为,我们在 Safari 上登录时出现错误,但在 Chrome 上却没有。

据我了解,这是因为会话 cookie 在我们第一次进行身份验证时被设置,它存储statecode-verifier(仅当使用 PKCE 流时)和 OIDC 客户端验证身份验证所需的其他值。

但是,当 /callback URL 被命中时,浏览器会将此会话 cookie 发送到服务器以完成身份验证。

每当未发送此 cookie 时,就会发生此错误,因为回调假定这是一个新请求并且它崩溃了......

对我们来说,这有两种表现方式。

  1. Cookie { 同一站点:'Lax' 安全:true }

    适用于 chrome,但这不适用于 safari

  2. Cookie { 同一站点:'无' 安全:true }

    适用于 chrome 和 safari

这需要在 express-session 中间件上设置(抱歉,我不确定所需的语法)


查看完整回答
反对 回复 2022-12-22
?
桃花长相依

TA贡献1860条经验 获得超8个赞

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

看这篇文章


查看完整回答
反对 回复 2022-12-22
?
波斯汪

TA贡献1811条经验 获得超4个赞

使用瀑布异步功能可能对此有所帮助。只需将 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

            })   

        );

    });


查看完整回答
反对 回复 2022-12-22
  • 4 回答
  • 0 关注
  • 95 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信