Google app engine Google app engine在授权socket.io连接时删除会话cookie

Google app engine Google app engine在授权socket.io连接时删除会话cookie,google-app-engine,session,socket.io,express-session,Google App Engine,Session,Socket.io,Express Session,当用户打开WebSocket连接时,我试图从express会话获取用户的sessionID。下面的代码显示了如何做到这一点。问题是,当我将服务器部署到google app engine时,在授权套接字连接时,我再也看不到会话cookie。它在本地运行时工作正常,所以谷歌应用程序引擎必须做些什么来删除cookie?我对谷歌应用程序引擎不太熟悉,因此非常感谢您的帮助 我在网上找到了很多不同的解决方案,比如npm的passport.socketio,我相信其中很多都实现了我自己编写的相同解决方案 编辑

当用户打开WebSocket连接时,我试图从express会话获取用户的sessionID。下面的代码显示了如何做到这一点。问题是,当我将服务器部署到google app engine时,在授权套接字连接时,我再也看不到会话cookie。它在本地运行时工作正常,所以谷歌应用程序引擎必须做些什么来删除cookie?我对谷歌应用程序引擎不太熟悉,因此非常感谢您的帮助

我在网上找到了很多不同的解决方案,比如npm的passport.socketio,我相信其中很多都实现了我自己编写的相同解决方案

编辑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);

});
更具体地说,从本地主机运行时,
data.headers.cookies
包含
io
connect.sid
express.sid
cookie。在谷歌应用程序引擎上运行时,它只包含
io
cookie。(编辑结束)

编辑2:


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);

});
我认为由于谷歌的自动缩放,我的服务器可能会出现不同的实例,因此我在
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);

});
所以我希望cookies['express.sid']中包含sessionID,但在谷歌应用程序引擎上它是空的

应用程序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

由于网络或应用程序配置的原因,在GAE上运行时,应用程序很可能无法从会话存储中检索用户。有关您正在使用的会话存储、express中的配置以及app.yaml的更多信息将更有助于解决此问题。GAE不太可能从HTTP响应头中删除cookie

我发现为了在express/express会话中使用redis,我需要在
app.yaml
中设置网络名称

network:
  name: default
不幸的是,您似乎无法在标准环境中使用此选项,因此我还必须更改:

runtime: nodejs
env: flex
在切换到灵活的环境时,还需要在
package.json
中指定引擎

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

谢谢,我将尝试一下应用程序的配置,看看这是否会改变什么。我不认为能够访问会话存储有什么问题,但是在WebSocket之外它工作得很好,但是我还没有能够测试它,因为我甚至无法获取会话ID来检索用户。-在我的问题中还添加了会话存储(MemoryStore)和app.yaml。更新:使用flex环境也不起作用,我想知道是否有可能拦截socket.io为建立套接字连接而发出的初始HTTP请求。我想你可以毫无问题地把sessionID放在那里,即使经过一些研究,我也不知道怎么做