Mern Stack:Passport.js谷歌认证在生产中不起作用(heroku和firebase)



我的应用程序在localhost中按预期工作,但当我将express后端部署到heroku并将前端响应到firebase时,谷歌身份验证将停止工作。

heroku日志中,我从谷歌获取用户配置文件,并从序列化和反序列化函数获取用户日志,但当我请求获取当前用户时,我会得到未定义的信息。

由于某些原因,服务器没有在浏览器中设置cookie,当我在浏览器中打开存储中的cookie时,我找不到任何会话cookie。

我尝试了在互联网上找到的所有可能的解决方案,但问题仍然存在。

编辑

我把我的前端移到了heroku,并从cookie选项中删除了域,这一次它可以工作,但只在私人模式下工作,你知道为什么它不能在正常模式下工作吗?

这是代码:

server.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}!`));

passport.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";

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

我的错误是我忘记在普通chrome选项卡的url栏中添加https://,当url不安全(http(时,普通chrome标签不接受cookie,只有匿名模式接受http中的cookie。

当我把react应用程序移到heroku时,我还从cookie选项(server.js(中删除了域。(但我认为你应该在托管到firebase时保留它(

也许没有必要离开firebase,我相信当我的前端托管在firebase上时,我也犯了同样的错误。。但我现在懒得检查

最新更新