oauth-2.0 梅恩·斯塔克:Passport.js google auth在生产中不工作(heroku和firebase)

cunj1qz1  于 2022-10-31  发布在  Go
关注(0)|答案(1)|浏览(105)

我的应用程序在localhost中按预期工作,但当我将express后端部署到heroku并将前端React到firebase时,google身份验证停止工作。
heroku日志中,我从google获取用户配置文件,并从序列化和反序列化函数获取用户日志,但当我请求获取当前用户时,我得到了未定义的用户。
由于某种原因,服务器没有在浏览器中设置cookie,当我在浏览器中打开存储的cookie时,我找不到任何会话cookie。
我尝试了我在互联网上找到的每一个可能的解决方案,但问题仍然存在。

编辑

我把我的前端到heroku和删除域从cookie选项,这一次它的工作,但只有在私人模式,任何关于为什么它不工作在正常模式的想法?
下面是代码:

服务器.js

import express from "express";
import mongoose from "mongoose";
import passport from "passport";
import "./passport.js";
import routerLogin from "./routes/auth.js";
import routerUser from "./routes/user.js";
import cookieSession from "cookie-session";
import cookieParser from "cookie-parser";

import { createRequire } from "module"; 
const require = createRequire(import.meta.url);

require("dotenv").config();
const bodyParser = require("body-parser");

const morgan = require("morgan"); 

import cors from "cors";

const app = express();
app.use(cookieParser());
app.use(
  cors({
    origin: "https://appname-339620.firebaseapp.com",
    credentials: true,
    methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
  })
);
app.use(bodyParser.json());

// db connection
mongoose
  .connect(process.env.DATABASE, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => console.log("DB Connected"))
  .catch((err) => console.log("DB Connection Error: ", err));

//middlewares
app.use(morgan("dev"));
app.use(express.json());

app.set("trust proxy", 1);

app.use(
  cookieSession({
    name: "SocialMedia-auth-session",
    secret: process.env.SESSION_SECRET,
    httpOnly: true,
    secure: true,
    sameSite: "none",
    domain: "https://appname-339620.firebaseapp.com/", 
  })
);

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

// routes
app.use("/", routerLogin);
app.use("/", routerUser);

const port = process.env.PORT || 8000;
app.listen(port, () => console.log(`the app listening on port ${port}!`));

护照.js

import passport from "passport";
import User from "./models/user.js";
import Google from "passport-google-oauth20";

const GoogleStrategy = Google.Strategy;

import { createRequire } from "module"; 
const require = createRequire(import.meta.url);
require("dotenv").config();

passport.serializeUser((user, done) => {
  console.log("user from serialize", user);
  done(null, user.id);
});

passport.deserializeUser(async (id, done) => {
  const user = await User.findById(id).populate("bookmarks");
  console.log("user from deserialize", user);
  done(null, user);
});

passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_APP_ID,
      clientSecret: process.env.GOOGLE_APP_SECRET_KEY,
      callbackURL: "/auth/google/callback",
      proxy: true,
    },
    async (accessToken, refreshToken, profile, done) => {
      console.log("profile from google =>", profile); 
      const user = await User.findOne({ GoogleID: profile.id });
      if (!user) {
        const newUser = await User.create({
          GoogleID: profile.id,
          name: profile.displayName,
          email: profile.emails[0].value,
          picture: profile.photos[0].value,
        });
        if (newUser) {
          done(null, newUser);
        }
      } else {
        done(null, user);
      }
    }
  )
);

auth.js中回调路由

routerLogin.get(
  "/auth/google/callback",
  passport.authenticate("google", {
    successRedirect: "https://appname-339620.firebaseapp.com", 
    failureRedirect: "https://appname-339620.firebaseapp.com/error",
  })
);

当前用户路由

routerUser.get("/auth/user", async (req, res) => {
  console.log("req.user =>", req.user); // undefined in production
  res.send(req.user);
});

对当前用户的axios调用

useEffect(() => {

    const ourRequest = axios.CancelToken.source();
    const fetchUser = async () => {
      try {
        const res = await axios.get(
          "/auth/user",
          {
            withCredentials: true,
          },
          { cancelToken: ourRequest.token }
        );
        if (res.data) {
          setUser({ user: res.data, loggedIn: true });
        }

        }
      } catch (err) {
        setUser({ ...state, userError: true });
        showNotification({  // I get this error notification when I try to connect in production
          color: "red",
          message: "failed to connect ! ",
          autoClose: 5000,

          disallowClose: true,
          icon: <AlertOctagon size={22} strokeWidth={1} color={"white"} />,
        });

      }
    };
    fetchUser();
    return () => ourRequest.cancel;
  }, []);

app.js中axios默认基本URL

axios.defaults.baseURL = "https://nameapp.herokuapp.com";

google设置中的授权重定向URIhttps://nameapp.herokuapp.com/auth/google/callback

sbdsn5lh

sbdsn5lh1#

我的错误是我忘了在普通chrome标签的url栏中添加https://,当url不安全(http)时,普通chrome标签不接受cookie,只有在匿名模式下才接受http中的cookie。
当我把我的react应用程序移到heroku时,我也从cookie选项(server.js)中删除了域。(但是我认为你应该在托管到firebase时保留它)
也许没有必要从firebase移动,我相信我在firebase上托管前端时也犯了同样的错误..但我现在懒得检查它

相关问题