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