我试图在用户打开WebSocket连接时从快速会话中获取用户的sessionID。下面的代码显示了这是如何完成的。问题是,当我将服务器部署到谷歌应用引擎时,我在授权套接字连接时无法再看到会话cookie。它在本地运行时工作正常,因此谷歌应用引擎必须做一些事情来删除cookie?我不太熟悉谷歌应用程序引擎所以任何帮助将不胜感激。
我在网上找到了许多不同的解决方案,例如来自npm的passport.socketio,其中很多我认为实现了与我自己编写完全相同的解决方案。
编辑1:
更具体地说,data.headers.cookies
在从localhost运行时包含io
,connect.sid
和express.sid
cookie。在谷歌应用引擎上运行时,它只包含io
cookie。 (编辑完结)
编辑2:
我认为由于谷歌的自动缩放而导致我的服务器具有不同的实例可能会出现问题,所以我在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,但在谷歌应用引擎上它是空的。
的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
由于网络或应用程序配置,在GAE上运行时,您的应用程序更有可能无法从会话存储中检索用户。有关您正在使用哪个会话存储的更多信息,Express中的配置以及app.yaml将更有助于解决此问题。 GAE不太可能从HTTP响应头中删除cookie。
我发现为了使用带有快速/快速会话的redis,我需要在app.yaml
中设置网络名称。
network:
name: default
不幸的是,似乎你不能在标准环境中使用它,所以我也不得不改变:
runtime: nodejs
env: flex
并且还需要在切换到灵活环境时在package.json
中指定引擎。
"engines": {
"node": "10.x"
}