NodeJS google Oauth2工作完美,但部署到Heroku会阻止google Oauth2工作[已解决]

6l7fqoea  于 2023-01-08  发布在  Node.js
关注(0)|答案(1)|浏览(137)

我最近做了一个react应用程序,它使用了google的Oauth2服务,在我的服务器上我使用了nodeJS的google单点登录,在localhost上它运行得很好,我可以存储会话,登录和退出,当我把这个nodejs应用程序部署到heroku上时,我可以打开google单点登录页面,点击我的用户账户,然后返回到我的应用程序。
但是,没有数据返回到我的应用程序,没有用户配置文件发送到我的应用程序。

const GoogleStrategy = require("passport-google-oauth2").Strategy;
const passport = require("passport");

const GOOGLE_CLIENT_ID = "HIDDEN_KEYmpt.apps.googleusercontent.com";
const GOOGLE_CLIENT_SECRET = "HIDDEN_KEY";

passport.use(
    new GoogleStrategy(
        {
            clientID: GOOGLE_CLIENT_ID,
            clientSecret: GOOGLE_CLIENT_SECRET,
            callbackURL: "/auth/google/callback",
            proxy: true,
        },
        function (accessToken, refreshToken, profile, done) {
            // usually here it will finish the google authentication process
            // and return profile user info, like the google account's email address, etc
            // on localhost it returns all that, on heroku it returns nothing
            done(null, profile);
        }
    )
);

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

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

我确保我添加了Heroku链接到谷歌Oauth2认证网站列表中,这很好用。我确保我的数据是从localhost正确接收的,就代码而言,当没有部署到Heroku时,它工作得很好。
更新:这是google auth逻辑的额外NodeJS代码

const CLIENT_URL = "https://mygituhbpageslink/home";

authRouter.get("/login/success", (req, res) => {
    // This is where the req.user SHOULD be returned after logging in, but it doesn't find a req.user so it fails
    if (req.user) {
        res.status(200).json({
            success: true,
            message: "SUCCESS!",
            user: req.user,
        });
    } else {
        res.send(JSON.stringify({
            success: false,
            message: "REQUEST FAILED!",
            user: [],
        }));
    }
});

authRouter.get("/login/failed", (req, res) => {
    res.status(401).json({
        success: false,
        message: "failure",
        user: [],
    });
});

authRouter.get("/logout", (req, res) => {
    req.logout();
    res.redirect(CLIENT_URL);
});

authRouter.get("/google", passport.authenticate("google", { scope: ["email"] }));

authRouter.get(
    "/google/callback",
    passport.authenticate("google", {
        successRedirect: CLIENT_URL,
        failureRedirect: "/auth/login/failed",
    })
);

module.exports = authRouter;

这里还有一个明确的逻辑

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const passport = require('passport');
const session = require('express-session');
const passportSetup = require("./Auth/passport");

const moviesRouter = require('./routes/movies');
const gamesRouter = require('./routes/games');
const booksRouter = require('./routes/books');
const authRouter = require('./routes/auth');

const app = express();

app.use(helmet());
app.use(express.json());

app.use(session({
    secret: "secret",
    resave: false,
    saveUninitialized: true,
    proxy: true,
}))

app.use(passport.initialize());
app.use(passport.session());

app.use(cors({
    origin: 'https://mygithubpages.github.io',
    methods: 'GET, POST, PUT, DELETE',
    credentials: true,
}));

// --------------- Routes --------------- //
app.use("/auth", authRouter);
// other routes

module.exports = app;
fnatzsnv

fnatzsnv1#

请尝试更新此信息,因为如果您在Heroku上托管Cookie,则Cookie是跨站点的,当您收到来自google Oauth2.0的回调时,Cookie会设置到您的浏览器,当您要在前端进行身份验证请求时,您需要能够在请求标头上获得此Cookie:

const app = express();

app.use(helmet());
app.use(express.json());

// is better to put the cors setting on the top
app.use(cors({      
origin: 'https://mygithubpages.github.io',
methods: 'GET, POST, PUT, DELETE',
credentials: true,
}));

app.set('trust proxy', 1)  // you need to add this
app.use(session({
    secret: "secret",
    resave: false,
    saveUninitialized: false,
    proxy: true,  // this is optional it depend which server you host, i am not sure about Heroku if you need it or not
    cookie: { 
        secure: "auto",  // this will set to false on developement, but true on Heroku since is https so this setting is required
        maxAge: 10000 // 10 sec for testing
        sameSite: "none", //by default in developement this is false if you're in developement mode
    },
}))

请注意express-session将会话存储在后端/数据库中,如果您没有在cookie的属性中定义存储位置,express-session将默认存储在MemoryStore中,这不是专门为生产环境设计的。仅用于调试和开发,您需要使用兼容的会话存储。您可以查看express session文档:https://github.com/expressjs/session

相关问题