Мой веб-сайт представляет собой приложение expressjs, которое упаковывается в образ докера и работает в AWS Fargate за ALB. Пользователи с большим количеством файлов cookie в домене (~ 7 КБ) сталкиваются с ошибкой HTTP 400. Однако, если пользователь очистит свои файлы cookie, проблема исчезнет, по крайней мере, на несколько дней, пока удаленные файлы cookie не будут переустановлены. Я являюсь одним поддоменом в этом домене, и у меня нет политического влияния, чтобы уменьшить количество файлов cookie или способ их установки; Я работаю в крупной компании.
Я устранил причину ошибки в ALB. Метрика CloudWatch, HTTPCode_ELB_4XX_Count равна 0, в то время как HTTPCode_Target_4XX_Count резко возрастает, когда я тестирую эту ошибку.
Моя диагностическая настройка выглядит следующим образом: в моей предварительной учетной записи AWS я установил для переменной среды DEBUG
значение *
в контейнере. Я также сократил проверку работоспособности целевой группы, чтобы она выполнялась каждые 5 минут (чтобы уменьшить количество болтовни), и уменьшил количество задач до 1 (чтобы централизовать журналы в один поток cwlog). Expressjs должен регистрировать все входящие запросы, которые он направляет, с подробностями, аналогичными странице отладки Expressjs, однако абсолютно ничего не выводится в лог. Как будто запрос не доходит до ExpressJS. Я подумал, может быть, я напортачил с настройкой, но проверка в режиме инкогнито выводит много отладочных заявлений.
Используя Postman, я скопировал заголовок файла cookie из Chrome CDT; Я продолжаю получать тот же результат 400 с заголовком Connection: close
, включенным в ответ. Я использую модуль express-sessions
, и если я удалю файл cookie сеанса (connect.sid
), запрос сработает. Если я удалю все куки кроме connect.sid
(сохранив старое значение), то запрос сработает. Если я отправлю все файлы cookie, но обновлю connect.sid
до значения, возвращаемого Set-Cookie
, запрос сработает.
Если я попробую те же тесты локально, используя docker-compose
, я не смогу воспроизвести ошибку ответа 400. Образы докеров одинаковы как в docker-compose, так и в fargate. Оба используют postgres через модуль connect-pg-simple
в качестве хранилища сеансов. Так что потенциально что-то может быть в сетевом стеке AWS или среде выполнения AWS Fargate.
Соответствующие зависимости в package.json:
"connect-pg-simple": "^5.0.0",
"express": "^4.16.4",
"express-session": "^1.11.1",
"helmet": "^3.15.0",
"method-override": "^3.0.0",
"morgan": "^1.9.1",
"pg": "^7.6.1",
Вот некоторые выдержки из моего кода. Я включил другие библиотеки установки на случай, если они конфликтуют, но не указал паспорт.
const express = require('express');
const compression = require('compression');
const helmet = require('helmet');
const methodOverride = require('method-override');
const pg = require('pg');
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const sessionStore = new pgSession({
pool: new pg.Pool()
});
const app = express();
app.use(methodOverride());
app.use(compression());
app.use(helmet({
// helmet settings omitted
}));
app.enable('trust proxy'); // Process X-Forwarded-* headers
app.use(session({
cookie: {
httpOnly: true,
secure: true
},
name: 'connect.sid',
resave: false,
saveUninitialized: true,
secret: 'some secret here',
store: sessionStore
}));
// rest of the code
Буду рад любым советам, указателям, предложениям, уточняющим вопросам. Потратив на это несколько часов, я мог использовать свежий взгляд.