Google app Engine удаляет сеансовые файлы cookie при авторизации сокета.подключение ввода-вывода

#google-app-engine #session #socket.io #express-session

#google-app-engine #сеанс #socket.io #экспресс-сессия

Вопрос:

Я пытаюсь получить идентификатор сеанса пользователя из express-session, когда пользователь открывает соединение с WebSocket. Приведенный ниже код показывает, как это делается. Проблема в том, что когда я развертываю свой сервер в Google App Engine, я больше не вижу сеансовый файл cookie при авторизации подключения к сокету. Он отлично работает при локальном запуске, поэтому Google App Engine должен что-то делать для удаления файла cookie? Я не слишком хорошо знаком с Google App Engine, поэтому буду признателен за любую помощь.

Я перепробовал много разных решений, которые нашел в Интернете, таких как passport.socketio из npm, многие из которых, как я полагаю, реализуют то же решение, которое я в итоге написал сам.

Редактировать 1:

Чтобы быть более конкретным, data.headers.cookies содержит io , connect.sid и express.sid cookie при запуске с локального хоста. При запуске в Google App Engine он содержит только io файл cookie. (Конец редактирования)

Редактировать 2:

Я подумал, что это может быть проблемой с наличием разных экземпляров моего сервера из-за автоматического масштабирования Google, поэтому я изменил свои настройки, app.yaml чтобы убедиться, что этого не произойдет:

 network:
  session_affinity: true

manual_scaling:
  instances: 1

  

(Конец редактирования)

Код:

 
var session = require('express-session');
var MemoryStore = require('memorystore')(session);

var store = new MemoryStore({
  checkPeriod: 86400000
}); // Likely to switch to RedisStore

app.use(session({
  store: store,
  secret: 'jpcs-0001080900DRXPXL',
  saveUninitialized: false,
  resave: true,
  key: 'express.sid'
}));

// ...

io.set('authorization', (data, accept) => {

  if (data amp;amp; data.headers amp;amp; data.headers.cookie) {

    console.log('COOKIES:');
    console.log(data.headers.cookie);

    cookies_str = data.headers.cookie;
    cookies_arr = cookies_str.split(';');
    cookies = {};

    for (index in cookies_arr) {
      cookie = cookies_arr[index].split('=');
      if (cookie.length != 2) continue;
      key = cookie[0].replace(/ /g,'');
      val = cookie[1];
      cookies[key] = val;
    }

    if (!cookies['express.sid']) accept('User not signed in', null);

    // HERE IS MY PROBLEM:
    // When running from google app engine cookies['express.sid'] is null

    sessionId = cookies['express.sid'].split('.')[0].substring(4);
    data.sessionId = sessionId;

    store.get(sessionId, (err, session) => {
      if (!err amp;amp; session) {
        data.session = session;
        accept(null, true);
      }
      else if (err) accept('Could not get session', false);
      else if (!session) accept('Could not get session', false)
    });

  }

  accept('Could not get session', false);

});
  

Поэтому я ожидаю, что cookies [‘express.sid’] будут содержать в нем идентификатор сеанса, но в Google app Engine он равен нулю.

App.yaml

 runtime: nodejs10 # For Node.js 8, use runtime: nodejs8

#instance_class: F2

#env_variables:
  #BUCKET_NAME: "example-gcs-bucket"

handlers:
- url: .*
  secure: always
  redirect_http_response_code: 301
  script: auto

network:
  session_affinity: true

manual_scaling:
  instances: 1
  

Ответ №1:

Более вероятно, что ваше приложение не может получить пользователя из хранилища сеансов при запуске в GAE из-за конфигурации сети или приложения. Дополнительная информация о том, какое хранилище сеансов вы используете, его конфигурация в express и app.yaml были бы более полезны для решения этой проблемы. Маловероятно, что GAE удалит файл cookie из заголовков HTTP-ответа.

Я обнаружил, что для использования redis с express / express-session мне нужно было указать имя сети app.yaml .

 network:
  name: default
  

К сожалению, похоже, что вы не можете использовать это для стандартных сред, поэтому мне также пришлось изменить:

 runtime: nodejs
env: flex
  

А также необходимо указать механизм package.json при переключении на гибкую среду.

 "engines": {
  "node": "10.x"
}
  

Комментарии:

1. Спасибо, я собираюсь поиграть с конфигурацией приложения и посмотреть, изменится ли что-нибудь. Я не думаю, что это проблема с возможностью доступа к хранилищу сеансов, хотя оно отлично работает за пределами websockets, но я еще не смог это проверить, поскольку я даже не могу получить идентификатор сеанса для извлечения пользователя. — Также добавляю хранилище сеансов (MemoryStore) и app.yaml на мой вопрос.

2. Обновление: использование среды flex также не сработало, интересно, возможно ли перехватить начальный сокет HTTP-запроса. ввод-вывод позволяет установить соединение с сокетами. Я бы подумал, что вы могли бы получить там идентификатор сеанса без каких-либо проблем, я не знаю, как это сделать, хотя даже после некоторых исследований