简体   繁体   English

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

[英]NodeJS google Oauth2 works perfectly, but deployment to Heroku stops google Oauth2 from working [SOLVED]

I recently made a react app that utilized the google Oauth2 service.我最近制作了一个使用 google Oauth2 服务的 React 应用程序。 For my server I use nodeJS single sign on with google, on localhost it works perfectly and I'm allowed to store the sessions and log in and out.对于我的服务器,我在 google 上使用 nodeJS 单点登录,在本地主机上它运行良好,我可以存储会话并登录和注销。 When I deploy this same nodejs app to heroku I am able to open the google single signon page, click my user account, and return to my app.当我将这个相同的 nodejs 应用程序部署到 heroku 时,我能够打开谷歌单点登录页面,单击我的用户帐户,然后返回到我的应用程序。

BUT, no data is being returned to my application, no user profile is being sent to my app.但是,没有数据返回到我的应用程序,没有用户配置文件被发送到我的应用程序。

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);
});

I made sure I added my Heroku link to the google Oauth2 list of verified websites, that works fine.我确定我将我的 Heroku 链接添加到经过验证的网站的 google Oauth2 列表中,效果很好。 I made sure that my data was being received correctly from localhost, as far as the code is concerned, it works perfectly when not deployed to Heroku.我确保我的数据从本地主机正确接收,就代码而言,它在未部署到 Heroku 时工作完美。

UPDATE: here is the extra NodeJS code for the google auth logic更新:这里是谷歌授权逻辑的额外 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;

And also here is the express logic这也是明确的逻辑

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;

Try to update this since your cookies is cross-site if you host it on Heroku, the cookie is set to your browser when you get the callback from google Oauth2.0, you need to be able to get this cookie on your request header when you re going to do the request on the frontend to authenticate:尝试更新它,因为如果您在 Heroku 上托管它,您的 cookies 是跨站点的,当您从 google Oauth2.0 获得回调时,cookie 将设置到您的浏览器,您需要能够在您的请求 header 时获取此 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
    },
}))

Beware express-session is storing session on the backend / database, and if you don't defined where to store it in cookie's property, express-session will store it by default in MemoryStore, and this is purposely not designed for a production environment.当心 express-session 将 session 存储在后端/数据库中,如果您没有在 cookie 的属性中定义存储位置,则 express-session 将默认将其存储在 MemoryStore 中,这不是为生产环境设计的。 is meant only for debugging and developing, you will need to use a compatible session store.仅用于调试和开发,您需要使用兼容的 session 商店。 You can check on the express session documentation: https://github.com/expressjs/session您可以查看 express session 文档: https://github.com/expressjs/session

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM