【发布时间】:2020-05-22 21:45:04
【问题描述】:
我们有一个启用了express-session 和express-mysql-session 的NodeJS express 服务器。我们已经连接了会话数据库,并且可以验证是否正在创建会话。我们的应用程序将没有令牌 cookie 的用户重定向到 Auth0 进行身份验证,然后他们被重定向回我们的应用程序 /callback。它确实成功设置了允许我们的用户登录的 ID 令牌。但是,passport auth0 策略抱怨它无法验证身份验证状态。
'Unable to verify authorization request state.'
服务器代码如下,其他部分注释掉。连接到会话数据库是成功的,因为我们可以看到每个请求都创建了会话。
const options = {
database: process.env.SESSION_DB_NAME || "sessions",
host: process.env.SESSION_DB_HOST! as string,
password: process.env.SESSION_DB_PASSWORD! as string,
port: parseInt(process.env.SESSION_DB_PASSWORD || "3306", 10),
user: process.env.SESSION_DB_USER! as string,
};
const sessionStore = new MySQLStore(options);
app.use(
session({
cookie: {
httpOnly: true,
maxAge: 24 * 3600 * 1000, // 1 day
secure: true,
},
resave: false,
saveUninitialized: true,
secret: process.env.SESSION_SECRET!,
store: sessionStore,
})
);
app.get("/login", (request, response, next) => {
// if there is no session, it's a server error
if (!request.session) {
console.error(new Error("No session in /login"));
return response.status(500).send("Server error: No Session");
}
return passport.authenticate("auth0", {
scope: "openid email profile",
})(request, response, next);
});
console.log("router: Auth0 Callback");
app.get("/callback", (request, response, next) => {
const domain = request.hostname;
console.log(request.session);
passport.authenticate("auth0", (auth0Error, token, info) => {
// if there was a problem authenticating
if (auth0Error) {
console.error(auth0Error);
return response.status(500).send();
}
// ensure we have a session. The middleware should be giving us one.
if (!request.session) {
console.error("No session in /callback.");
return response.status(500).send();
}
// if we couldn't log in
if (!token) {
if (info) {
console.log(info);
return response.status(500).send(info.message);
}
// redirect to the login page
return response.status(401).send("Cannot log you in.");
}
// parse the token we get
const user = jwt.decode(token);
// if there is no valid user token, we've got bigger problems
if (!user) {
console.error("Token is falsey after authenticating.");
return response.status(500).send();
} else if (typeof user === "string") {
console.error("Cannot decode JWT after authenticating");
return response.status(500).send();
}
request.logIn(user, (logInError) => {
// redirect to desired route
// ...
});
})(request, response, next);
});
router.get("/*", (request, response, next) => {
passport.authenticate("jwt", (authenticationError, isAuthenticated, info) => {
// Log in successful via existing JWT
if (isAuthenticated) {
return next();
}
// handle unauthenticated situations
// ...
})(request, response, next);
});
我在https://github.com/auth0/passport-auth0/issues/70尝试了以下建议:
- app.set("信任代理", 1")
- 会话 cookie 已设置为安全
- 仅在 https 上提供服务
- 使用 mysql 会话存储和默认内存存储
我们在 kubernetes 集群中运行服务器,使用 ClusterIP 作为我们的入口。环境变量设置正确,我很确定。当我在本地运行它时,我没有任何问题。
什么可能导致会话无法恢复,而是随着每个请求重新创建?
【问题讨论】:
-
你是如何解决这个问题的?我遇到了同样的问题。我在 heroku 上运行 nodejs
-
@ChrisHansen 我不确定我们是否解决了这个问题。回顾我们的提交,我认为这更像是一种缓解。如果我们捕获到该异常日志,我们会自动尝试另一次登录尝试。
标签: node.js express session auth0