我使用的是passport.js本地策略。我是在代理设置下测试的,localhost。在我准备部署之前,一切都很好。
我将API地址更改为包含dotenv并在服务器端设置CORS设置。
-
当尝试登录时,CORS工作正常,选项和POST得到200 ok。客户端接收到成功数据。Cookie保存在客户端
-
但是当认证检查进程在Redux之后运行时,isLoggedin"状态被更新(useEffect),请求。会议不我有护照。所以不能调用deserializeUser。会话包含除Passport以外的其他cookie信息。
-
这个只在Firefox上(不是Chrome):如果登录验证成功,页面将被重定向(它在登录redux状态改变后立即检查),但由于它失败了,用户仍然停留在登录页面上。但是如果我尝试再次登录同一页面,cookie就会开始显示护照对象。(换句话说,它显示从第二次尝试)。但是它不会持续存在,因为Redux登录状态在第一次登录尝试时已经被更改为true。(因此验证检查不会发生)
客户机:
Axios.post(
`${process.env.REACT_APP_API_URI}/api/users/login`,
loginData,
{ withCredentials: true, }
).then((res) => res.data){
//save isLoggedin to true in Redux
}
// auth check logic starts right after changing isLoggedin. Axios Get to authenticateCheck
server.js
app.use(helmet());
// app.use(express.static('public'));
app.use("/uploads", express.static("uploads"));
// Passport configuration.
require("./utils/passport");
// connect to mongoDB
mongoose
.connect(db.mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
})
.then(() => console.log("mongoDB is connected."))
.catch((err) => console.log(err));
// CORS Middleware
const corsOptions = {
origin: "http://localhost:8000",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
credentials: true,
methods: ["POST", "GET", "DELETE", "PUT", "PATCH", "OPTIONS"],
allowedHeaders:
"Origin, X-Requested-With, X-AUTHENTICATION, X-IP, Content-Type, Accept, x-access-token",
};
// app.use(cors(corsOptions));
app.options(/.*/, cors(corsOptions), function (req, res) {
return res.sendStatus(200);
});
app.all("*", cors(corsOptions), function (req, res, next) {
next();
});
// to get json data
// support parsing of application/json type post data
app.use(express.json());
app.use((req, res, next) => {
req.requestTime = new Date().toISOString();
next();
});
//support parsing of application/x-www-form-urlencoded post data
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
// db session store
const sessionStore = new MongoStore({
mongoUrl: db.mongoURI,
collection: "sessions",
});
// tell app to use cookie
app.use(
session({
secret: process.env.SESSION_SECRET_KEY,
resave: false,
saveUninitialized: false,
store: sessionStore,
cookie: {
httpOnly: true,
secure: false,
sameSite:"none",
maxAge: 24 * 60 * 60 * 1000, // 24 hours
//keys: [process.env.COOKIE_ENCRYPTION_KEY]
},
name: "pm-user",
})
);
// tell passport to make use of cookies to handle authentication
app.use(passport.initialize());
app.use(passport.session());
app.use(compression());
app.use(flash());
app.use((req, res, next) => {
console.log("req.session:", req.session);
// console.log('/////// req: ///////', req);
console.log("////// req.user: ", req.user, " //////");
next();
});
//---------------- END OF MIDDLEWARE ---------------------//
authController:
exports.authenticateCheck = (req, res, next) => {
console.log("req.isAuthenticated():", req.isAuthenticated());
if (req.isAuthenticated()) {
return next();
} else {
return res.json({
isAuth: false,
error: true,
});
}
};
如果你能告诉我在哪里修理它,那将是一个很大的帮助。谢谢。我终于找到了解决办法。这是因为除了登录请求之外,每次启动新请求时都会更新会话。解决方案是,我必须在我的前端的每个Axios选项中添加{withCredentials: true}。