Я столкнулся с проблемой, пытаясь внедрить HTTPS через прокси-сервер (первоначально NGINX, теперь AWS ALB) для защиты соединений с моим сервером узла. Мой запрос login обрабатывается нормально, но последующие запросы после login помечаются как isAuthenticated === false, и поэтому мое приложение node возвращает 401.
Я знаю, что isAuthenticated === false вызван тем, что файл cookie сеанса не установлен в браузере, однако я не могу понять, почему файл cookie сеанса не устанавливается (или не отправляется?).
Я настраиваю экспресс-сеанс, как показано ниже:
app.use(cookieParser('secret'));
app.set('trust proxy', 1);
// add & configure middleware
app.use(session({
name: 'session',
store: new redisStore(),
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true,
secure: true }
}));
Приложение моего узла находится за балансировщиком нагрузки приложений AWS, который связывается с приложением через HTTP, поэтому я настроил trust proxy на 1.
Моя конфигурация паспорта и локальная стратегия находятся чуть ниже:
// configure passport.js to use the local strategy
passport.use(new LocalStrategy(
{ usernameField: 'email' },
(email, password, done) => {
mysql.getConnection((err, conn) => {
conn.query('SELECT u.user_id, u.email, u.password, o.uuid FROM user AS u INNER JOIN organization AS o ON o.id = u.org_id WHERE email = ?;', [email], ( err, rows ) => {
if (err) throw err;
if (rows.length !== 1)
return done(null, false, { message: 'User does not exist.\n' });
else if (!bcrypt.compareSync(password, rows[0].password))
return done(null, false, { message: 'Incorrect password.\n' });
else{
return done(null, {user_id: rows[0].user_id, email: email, uuid: rows[0].uuid});
}
});
conn.release();
});
}
));
Запрос, исходящий от реагирующего клиента:
axios.post('https://sub.mydomain.com' + '/api/login', userObj, {withCredentials: true})
.then(res => {
if (res.status === 200) {
initUser(res.data, true);
}
else {
this.setState({errors: {password: 'Incorrect username or password'}})
this.props.history.push('/login');
}
})
.catch((e) => {
this.setState({errors: {password: 'Unable to login'}})
this.props.history.push('/login');
});
При выполнении запроса мне возвращается статус 200 с информацией о пользователе, как я и ожидал. Смотрите скриншоты из PostMan ниже:

Также это заголовки ответов в Chrome:
access-control-allow-credentials: true
access-control-allow-origin: https://sub.mydomain.com
content-length: 89
content-type: text/html; charset=utf-8
date: Tue, 12 Mar 2019 07:49:45 GMT
etag: W/"59-T0xi+VpB6A/MLCHMb8Qz3Pq9dwc"
status: 200
vary: Origin
x-powered-by: Express
Где-то в строке кажется, что файл cookie сеанса либо не может быть отправлен из приложения узла, либо установлен в браузере.
Я запускаю то же самое на своем локальном компьютере, и файл cookie устанавливается в браузере без проблем. Единственная разница между моим локальным и моим сервером — это ALB перед приложением node, и я устанавливаю secure: false на своем локальном (поскольку я не использую HTTPS).
К сведению: сначала я пытался использовать NGINX proxy_pass на своем сервере для обработки HTTPS-соединений, и у меня возникла та же проблема. Я попытался удалить прокси-проход и использовать балансировщик нагрузки приложений AWS после того, как не смог найти решение с NGINX (я думал, что может быть проблема с моей конфигурацией NGINX). Это приводит меня к мысли, что проблема связана с конфигурацией экспресс-сеанса как с общим знаменателем здесь, однако я могу упустить что-то еще.
FYI 2 — я пытался установить trust proxy на true, 1, 2, 3 и т. д. Также пытался установить secure на false, Также пытался установить httpOnly на false — и бесчисленные варианты вышеперечисленного, но все же я не кажусь получение куки в браузере.
FYI 3. Я попытался удалить прокси-сервер и вернуться к прямому HTTP-соединению с приложением Node, но я все еще не получаю файл cookie в своем браузере (или в PostMan).
Надеюсь, что кто-то здесь может указать на что-то, что я пропустил, в надежде решить эту проблему.
Заранее спасибо!





Итак, после нескольких дней расследования проблема оказалась в том, что мой сервер Redis остановился и не смог перезапуститься. фейспалм
Идентификатор сеанса не создавался (или не сохранялся), так как он не мог подключиться к хранилищу Redis для сохранения информации о сеансе на стороне сервера.
Запуск сервера Redis немедленно решил проблему, однако было бы здорово, если бы в экспресс/паспорте был какой-то подробный журнал, чтобы уведомлять пользователей об этом.
Надеюсь, кто-то еще найдет это полезным!