我在这里描述的问题发生在我的本地开发机器上,浏览器请求和应用程序之间没有任何代理。我有几个Node.js微服务,它们共享用于管理会话的相同技术:
通常的流程看到用户在身份验证应用程序中登录,然后被重定向到前端(React应用程序),后端向后端微服务执行CORS请求,后端运行GraphQL服务器。这个问题与the one described here非常相似,即使我的配置略有不同(静态路由仅在auth应用程序中,在会话定义之前使用,false
用于resave
和saveUninitialized
选项)。
两个身份验证/后端应用程序都具有以下配置:
const sessionOptions = {
store: new RedisStore({
client: redisClient,
disableTTL: true,
}),
secret: "123",
resave: false,
saveUninitialized: false,
proxy: false,
rolling: true,
cookie: {
domain: config.cookie.domain,
sameSite: config.cookie.sameSite,
maxAge: toTime(config.cookie.maxAge).ms(),
secure: config.cookie.secure,
},
};
app.use(session(sessionOptions));
// Configure passport middleware
app.use(passport.initialize());
app.use(passport.session());
后端应用程序具有额外的CORS配置:
app.use(cors({
origin: "frontend_url",
credentials: true,
methods: ['GET', 'POST'],
}));
初始Redis状态:
127.0.0.1:6379> KEYS "*"
(empty list or set)
我转到登录页面并创建了一个会话:
127.0.0.1:6379> KEYS "*"
1) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"
我登录,会话仍然是一个,直到我被重定向到我的React应用程序,然后我得到六个新会话:
127.0.0.1:6379> KEYS "*"
1) "sess:NNWse-sp51fVRf6rlnsFpMlZO1gkPgYC"
2) "sess:ofQhH0iBbZOvsJBYMxwHjLL0DKxuFKfS"
3) "sess:XxsTGSoANPE5-fPYbwLmoCgvDho0NTnk"
4) "sess:9wFDQ3_RibJyEXEmJ_8gCxfnak4Uh0yP"
5) "sess:8khC8fgbtO53mJNilMhp88toIcsizxea"
6) "sess:jfQBWogefBr75IgZ5GykSgd5d3t3Mt_D"
7) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"
无论我点击什么链接,它都会将它们的数量增加到16,依此类推。我无法发现任何请求我的后端没有发送会话cookie但OPTION飞行前请求。所以我尝试使用my own configuration instead than CORS module,但没有任何改变。如果我退出,显然只是从Redis中删除了与我的会话cookie匹配的原始会话,其余的(因为我已禁用TTL进行“永久”会话)只是在那里摇晃。很明显,我不希望Redis充满无用的会话,但我找不到真正的问题。有什么建议?谢谢。
更新:如果我尝试使用自定义的东西修改genid
函数,我注意到了不同的行为:
null
(req.body.username
),则返回${req.body.username}_${uuidv4()}
。null
。对auth服务的第一个请求引发了一个异常invalid csrf
,因为可能它在Redis中找不到,因为genid
现在返回null。第二个请求(假设您使用与以前相同的电子邮件并且登录成功)将我引导到前端,这次我只能看到正在创建一个会话。显然,这不是一个正确的流程,但无论如何,奇怪的是它只在Redis中创建了一个会话。
几天前我遇到了同样的问题!我已经设置了我的回购并分享了我的链接!它完美无缺!看看吧。
最后,我发现了一些发送到我的auth服务的请求没有设置会话cookie,对于某些路径它甚至不应该被使用。所以我定义了与会话相关的路径:
const sessionPaths = ['/path1', '/path2', ...];
app.use(sessionPaths, session(sessionOptions));
app.use(sessionPaths, passport.initialize());
app.use(sessionPaths, passport.session());
app.use(sessionPaths, csrf());
不确定这是否已完全解决,但考虑到你如何解决它的顺序,你可能在会话处理程序之后有cors处理程序。由于没有会话cookie或凭证被发送,因此可能正在为每个会话创建会话中的预检请求。简单的解决方法是将cors处理程序移到会话处理程序之上。