【问题标题】:NodeJS Express Session isn't being restored between routes in kubernetesKubernetes 中的路由之间未恢复 NodeJS Express 会话
【发布时间】:2020-05-22 21:45:04
【问题描述】:

我们有一个启用了express-sessionexpress-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


【解决方案1】:

您的问题是一年多前发布的,所以我认为您已经修复了它,但我想我会发布我的解决方案来帮助其他人。我最近遇到了同样的问题,虽然我使用的是 Apache 反向代理而不是 Kubernetes 集群。

我在另一个 SO 问题中发布了我的解决方案:https://stackoverflow.com/a/67891167/8221175

简而言之,我的 Apache 配置缺少以下几行:

RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader set X-Forwarded-SSL expr=%{HTTPS}

ProxyPass / http://localhost:8001/
ProxyPassReverse / http://localhost:8001/

这与 express 的其他会话/cookie 配置(请参阅 SO 链接)一起修复了它。我的会话现在仍然存在,我不再遇到问题。

对于那些对“无法验证授权请求状态”的原因感兴趣的人。消息已发出,请在此 GitHub 问题中查看我的答案:https://github.com/auth0/passport-auth0/issues/89#issuecomment-856971807

【讨论】:

猜你喜欢
  • 2013-03-30
  • 2019-01-21
  • 2015-11-16
  • 2017-09-19
  • 1970-01-01
  • 2012-06-18
  • 2021-04-03
  • 2020-12-19
  • 1970-01-01
相关资源
最近更新 更多