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

На моем веб-сайте я включил опцию входа через Discord API и сохранения сеанса пользователя на моем сервере. Это прекрасно работает на локальном компьютере, но когда я развернул его на моем сервере digitalocean, он не работает.

То, что, похоже, происходит, - то, что на локальном компьютере есть cookie, сохраненный с некоторыми данными, которые, я полагаю, относятся к сеансу. Этот файл cookie никогда не создается и не сохраняется на развернутом веб-сайте. Когда я делаю запросы на локальном компьютере, идентификатор сессии всегда один и тот же, а на развернутом веб-сайте он отличается для каждого запроса.

Я попробовал почти все ответы, чтобы найти в Интернете эту проблему. Я установил и попробовал каждый заголовок прокси для Nginx. Я пробовал разные варианты на моем экспресс-сервере и экспресс-сессии.

Это опции по умолчанию

const sessionCfg: SessionOptions = {
  secret: secretConfig.sessionSecret,
  name: 'my-website-auth',
  resave: false,
  saveUninitialized: true,
  cookie: {
    maxAge: YEAR_IN_MS,
  },
};

...

app.use(session(sessionCfg));

А для производства добавляются

if (isProd) {
  // Trust first proxy
  app.set('trust proxy', 1);

  // Serve cookies over HTTPS
  sessionCfg.cookie.secure = true;
  sessionCfg.proxy = true;

  // Initialize Redis to store sessions
  const RedisStore = redisStoreInit(session);
  redisClient = redis.createClient();

  redisClient.on('error', (err) => {
    console.error('Redis error:', err);
  });

  redisClient.on('ready', () => {
    console.info('Redis ready');
  });

  sessionCfg.store = new RedisStore({
    host: '127.0.0.1',
    port: 6379,
    client: redisClient,
    ttl: 86400,
  });
}

Я также использую паспорт для использования DiscordStrategy

const discordStrategy = new DiscordStrategy(
  {
    clientID: secretConfig.discord.publicKey,
    clientSecret: secretConfig.discord.privateKey,
    callbackURL: discordConfig.callbackUrl,
    scope: discordConfig.scopes,
  },
  (accessToken, refreshToken, user, done) => {
    process.nextTick(() => {
      return done(null, user);
    });
  }
);

passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

passport.use(discordStrategy);

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

Это блок Nginx (закомментированные строки были опробованы ранее)

server {
        server_name api.something.com;

        location / {
                proxy_pass http://127.0.0.1:3002;
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;

                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;

                proxy_set_header X-Forwarded-Proto https;
                # proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $remote_addr;
                # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $host;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/.../fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/.../privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = api.something.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name api.something.com;
    return 404; # managed by Certbot
}

Я ожидаю, что идентификатор сессии будет одинаковым при каждом запросе, поэтому пользователь проходит проверку подлинности на сервере.

Что происходит, так это то, что при каждом запросе сессия меняется Пользователь не может быть аутентифицирован из-за этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...