Механизм приложений Google удаляет сеансовые куки при авторизации подключения socket.io - PullRequest
2 голосов
/ 13 апреля 2019

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

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

Edit 1:

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

Редактировать 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 && data.headers && 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 && 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);

});

Поэтому я ожидаю, что файлы cookie ['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 Ответ

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

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

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

network:
  name: default

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

runtime: nodejs
env: flex

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

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