【问题标题】:Unable to verify authorization state on Heroku无法在 Heroku 上验证授权状态
【发布时间】:2022-02-21 01:51:26
【问题描述】:

我正在 heroku 上运行一个 nodejs/reactjs 应用程序。我使用 Passport 实现了谷歌登录。当人们尝试登录时,我收到“无法验证授权状态”错误。

我在这里看到NodeJS Express Session isn't being restored between routes in kubernetes 我需要设置 X-Forwarded-SSL 标头。根据问题所说,我该怎么做?

该页面上概述的解决方案还提到了 Apache,但 Heroku 没有使用 Apache 将请求转发到应用程序的 Web dyno。

有人在 Heroku 上遇到同样的问题吗?

所以奇怪的是,当我尝试登录时,它第二次成功,但第一次,我收到错误“无法验证授权状态”。

这是我的 index.js

const session = require("express-session");
app.use (
    session ({
        secret: "ddd",
        resave: false,
        saveUninitialized: true,
        cookie: {
            expires: 60 * 60 * 24,
            secure: (app.get('env') === 'production')
        }
    })
);

if (app.get('env') === 'production') {
    app.set('trust proxy', 1); // trust first proxy
}

【问题讨论】:

  • 您好,抱歉回复晚了!请求标头可能不是问题,因为在我的问题中,会话从未持续存在,无论我尝试了多少次,我都会收到该错误。您能否验证,当您第一次登录时,正在设置一个 cookie,并且在您的会话表中创建了一个会话(确保在测试时没有 cookie)?您是否尝试过在您的 verify 函数和 serializeUser 函数中记录所有参数?
  • 另外,我假设您正在谈论通过 https 访问的已部署代码,对吗?还是你在本地主机上?
  • 我在安全环境中的生产环境中运行 heroku。所以是的(https)
  • 我第一次登录时没有设置cookie。
  • 我的 serializeUser 函数应该做什么?

标签: node.js reactjs heroku


【解决方案1】:

所以正如我提到的,您的问题可能与请求标头无关,因为在我的问题中,会话从未持续存在,而您的问题在您的第二次尝试中会持续存在。这可能是您的验证功能或deserializeUser 功能的问题。

这是一个例子。我个人不使用谷歌身份验证,而是使用其他东西。我的代码看起来很相似,但我从https://github.com/jaredhanson/passport-google/blob/master/examples/signon/app.js 获得了一些 Google 身份验证代码。在适当的地方填写您的内容并调试/记录传入的内容以查看您的函数是如何被调用的。

passport.use(new GoogleStrategy({
    returnURL: 'http://localhost:3000/auth/google/return', // replace with yours
    realm: 'http://localhost:3000/' // replace with yours
}, function (identifier, profile, done) { 
    // console.log identifier and profile, or even better, use your debugger on this line and see what's happening

    // Do whatever you need to do with identifier and then..
    return done(null, profile);
}));

passport.serializeUser(async (user, done) => {
    // console.log user or use your debugger on this line and see what's happening

    const userInDb = await db.getUser(user) // Find your user in your db using based on whatever is in the user object 
    const  serializedSessionUser = {id: userInDb.id, username: userInDb.username} // this is the object that'll appear in req.user. Customize it like you want
    return done(null, serializedSessionUser); // Commit it to the session
});

passport.deserializeUser((user, done) => {
    done(null, user);
});

编辑: 显然有两种方法可以使用 Google 获取护照。第一个是 OAuth / OAuth 2.0。第二个是OpenID。我在这个例子中使用了 OpenID。相应调整!

编辑 2: 这是我自己的 index.js 等价物:

app.use(session({
    cookie: {
        sameSite: 'lax',
        secure: !['development', 'test'].includes(process.env.NODE_ENV),
        maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
    },
    proxy: true,
    resave: false,
    saveUninitialized: true,
    secret: process.env.COOKIE_SECRET,
    store: 'your store',
    rolling: true,
}));

【讨论】:

猜你喜欢
  • 2012-07-07
  • 1970-01-01
  • 2018-10-31
  • 2017-01-02
  • 2022-01-21
  • 2017-08-02
  • 1970-01-01
  • 2021-09-27
  • 2014-06-15
相关资源
最近更新 更多