Экспресс сессия не сохраняет паспорт пользователя при хостинге на Heroku - PullRequest
0 голосов
/ 03 апреля 2019

Я разрабатываю веб-сайт, на котором пользователь может войти в систему и выполнить поиск по различным данным TfL, где я отправлю запрос в API в бэкэнде.Я размещаю свой интерфейс на Netlify и мой сервер на Heroku.Моя проблема в том, что когда пользователь нажимает кнопку входа в систему, данные сеанса показывают его идентификатор пользователя.Однако затем, когда пользователь перенаправляется на главную страницу, я снова распечатываю данные сеанса, но в сеансе отсутствует идентификатор пользователя.

Одно замечание: я перенаправляю пользователя в другой домен, когда онинажмите login через ajax, затем сервер аутентифицирует их, и в случае успеха я отправляю ответ о статусе 200 обратно на обратный вызов ajax, и там я использую window.location.href, чтобы продвинуть пользователя на главную страницу.

Я пробовал все виды вещей, такие как cors, устанавливая учетные данные в true, используя mongostore, почти все, о чем вы можете подумать.

Фрагмент моего внутреннего экспресс-кода

    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();
                }
            }
        });

Когда пользователь загружает главную страницу и делает запрос GET для / поиска, данные сеанса должны содержать паспорт: {user: -whwhat-}.Однако это не так, это как будто не сохраняет сеанс вообще.

Это вывод из журнала Heroku:

This is the output from the Heroku log:

Первый вывод информации о сеансе происходит до того, как пользователь направляется на главную страницу.Информация о втором сеансе выводится после того, как пользователь перенаправлен на главную страницу и сделан запрос GET для / search.

1 Ответ

0 голосов
/ 03 апреля 2019

ОБНОВЛЕНИЕ: я исправил свою проблему, очистив файлы cookie в браузере Chrome. Если у кого-то еще есть эта проблема, я рекомендую вам попробовать это! Кроме того, если вы используете 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();
    });

Надеюсь, это помогло любому, у кого возникли проблемы с этим! Если нет, не сдавайся!

...