当前位置: 首页 > 知识库问答 >
问题:

在Heroku上托管时,Express会话不保存passport用户id

仲法
2023-03-14

我正在开发一个网站,用户可以登录并搜索不同的TfL数据,我将在后端向API发送请求。我在netlify上托管前端,在Heroku上托管后端。我的问题是,当用户按下登录按钮时,会话数据会显示其用户id。但是,当用户重定向到主页时,我会再次打印会话数据,但会话中没有用户id。

需要注意的是,当用户通过ajax按login时,我将用户重定向到另一个域,然后后端对其进行身份验证,如果成功,我将向ajax回调发送200的状态响应,然后返回用户窗口。地方href将用户前进到主页面。

我尝试过各种各样的方法,比如cors,将凭证设置为true,使用mongostore,几乎所有你能想到的方法。

我的后端express代码片段

    function loggedIn(req, res, next) {
        console.log(req.session);
        if (req.user) {
            next();
        } else {
            res.sendStatus('501');
        }
    }

    app.use(cookieParser());

    // Express Session
    app.use(session({
        secret: "secret",
        cookie: {
            secure: true,
        },
        saveUninitialized: true,
        resave: true,
    }));

    app.use(passport.initialize());
    app.use(passport.session());

    passport.serializeUser((user, done) => {
        done(null, user.id);
    });

    passport.deserializeUser((id, done) => {
        User.getUserFromId(id, (err, user) => {
            done(err, user);
        });
    });

    app.post('/login', urlencodedParser, passport.authenticate('local', {failureRedirect: '/login-error', failureFlash: true}), (req, res) => {
        req.session.save( err => {
            res.send(req.user);
            console.log(req.session);
        });
    });

    app.get('/search', loggedIn, urlencodedParser, (req, res) => {
        Search.find({user: req.user._id}, (err, data) => {
            if(err) throw err;
            res.send({searches: data});
        });
    });

用户加载主页面后立即进行的AJAX调用

$.ajax({
        //The type of the request is a GET request.
        type: 'GET',
        //We're doing a GET request to that route.
        url: 'https://tfldatavis.herokuapp.com/search',
        data: '',
        xhrFields: {
            withCredentials: true
        },
        //On success of the request, some data will be sent back and this function wil be fired.
        success: data => {
            for(let i = data.length-1; i >= 0; i--) {
                $('#search-history').append('<span style="color: #2c313a">' + data.searches[i].search + '</span>');
            }
        },
        error: (err, data) => {
            if (data.status === 501) {
                window.location.href = 'https://www.emreedogan.com/login';
            }
        }
    });

当用户按下登录按钮时进行的AJAX调用

$.ajax({
            //The type of the request is a POST request.
            type: 'POST',
            //We're doing a POST request to that route.
            url: 'https://tfldatavis.herokuapp.com/login',
            //Pass along the data inside 'searchQuery' along with the request.
            data: user,
            xhrFields: {
                withCredentials: true
            },
            //On success of the request, some data will be sent back and this function wil be fired.
            success: data => { console.log(data); window.location.href = 'https://www.emreedogan.com/index'; },
            error: (req, status, err) => {
                const message = req.responseJSON.error[0];
                $('#error-message').text(message);
                if (message.indexOf("Email") >= 0) {
                    $('input[type="email"]').focus();
                } else if (message.indexOf("password") >= 0) {
                    $('input[type="password"]').focus();
                }
            }
        });

当用户加载主页并向 /search发出GET请求时,会话数据应该包括护照:{user:-whever-}。然而,它没有,就像它根本没有保存会话一样。

这是Heroku日志的输出:

第一个会话信息输出在用户被定向到主页之前。第二个会话信息输出是在用户被定向到主页并发出GET请求/搜索之后。

共有1个答案

屠建本
2023-03-14

更新:我通过清除Chrome中的浏览器cookie修复了我的问题。如果其他人有这个问题,我建议你也试试这个!此外,如果您使用AJAX向后端发出请求,请确保您在AJAX代码中包含以下内容:

xhrFields: {
    withCredentials: true
}

此外,如果您正在进行跨域请求,请确保您的后端可以接受这些请求:

app.use(function(req, res, next) {
        res.header('Access-Control-Allow-Credentials', true);
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
        next();
    });

我希望这能帮助任何有问题的人!如果没有,不要放弃!

 类似资料:
  • 问题内容: 我正在构建一个Node应用程序,用户必须在其中注册或登录,然后当他们拖放某些元素(前端都在工作)时,我将其操作及其相应的userId存储在数据库中。 我的理解是,一旦他们注册/登录,我就可以使用req.user来访问他们的ID并正确存储他们的操作,但是它不起作用。 这是我的server.js文件中处理Passport的部分。另外,我将Sequelize用作ORM,但是没有req.use

  • 我有一个Spring MVC Web应用程序,用户可以在该应用程序上登录和注册帐户。一旦用户登录并且用户注销会话结束,我将尝试保留会话。 实现这一点的最佳方式是什么? 以下是我的登录控制器。

  • 我有一个React应用程序在节点中调用API。js/Express。 前端部署在Netlify(https)中,后端部署在Heroku(https)中。 我的问题是: 在开发环境(localhost)中工作的所有内容 说话很便宜,给我看代码...... 我使用护照(本地策略),快速会话,cors。 应用程序。js CRUDendpoint(例如item routes.js): 使用Axios时,选

  • 问题内容: 我正在尝试在我的Express应用程序中使用redis进行会话。 我执行以下操作: 稍后,在我的应用程序中,如果执行以下操作: 我得到: 无法读取未定义的属性“ someProperty” 这表明req.session是未定义的 (我可以从config部分的console.log条目中看到) 我肯定有redis运行,并且可以看到我的应用最初连接到它(使用redis-cli监视器) 问题

  • 问题内容: 如果一个用户已经登录并尝试在新实例中再次登录,我希望它注销另一个用户实例。我不希望同一用户在我的应用程序上登录两次。 当前会话存储在Redis存储中,我正在使用express / connect处理会话存储。可以用来破坏会话的可用功能之一如下: 但是,我需要在调用.destroy()之前找到该会话ID。在Redis中,用户名存储为会话的一部分。 问题:是否可以查询Redis以基于用户名

  • 我在解决如何正确处理JSF中会话的自动销毁方面遇到了困难。当然,此时,容器会使会话失效,从而也会在会话范围的bean上调用@PreDestroy方法。 在某些会话范围bean的预销毁中,我们正在注销一些侦听器,如下所示: 然而,getWS()方法实际上试图获取对另一个会话范围bean的引用,但失败了,如返回null。Ryan Lubke认为,后者似乎是正常的JSF行为: 我们遵守这里的规范。我不确