在Heroku上托管时,Express会话不会保存护照用户ID

时间:2019-04-03 17:02:20

标签: node.js express heroku passport.js express-session

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

请注意,当用户通过ajax按下登录时,我会将用户重定向到另一个域,然后后端对其进行身份验证,如果成功,我将状态响应200发送回ajax回调,并在其中显示用户窗口.location.href将用户提升到主页。

我尝试了各种操作,例如cors,使用mongostore将凭据设置为true,几乎可以想到的大多数事情。

我的后端快递代码段

    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:-whatever-}。但是,事实并非如此,就像它根本不保存会话。

这是Heroku日志的输出:

This is the output from the Heroku log:

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

1 个答案:

答案 0 :(得分:0)

更新:我通过清除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();
    });

我希望这可以帮助遇到此问题的任何人!如果没有,请不要放弃!