如何解决使用 https 连接的 MERN 堆栈无法在 Chrome 上设置 cookie,但在所有其他浏览器上设置它们
我正在开发一个典型的 MERN 应用程序并且我已经完成了身份验证周期。我的 NodeJS/Express 后端使用“express-session”和“connect-mongodb-connection”来创建和处理会话。 React 前端使用“axios”与 API 进行通信。身份验证周期适用于除 Chrome 之外的所有浏览器。对于所有其他浏览器,在 MongoDB 中成功创建了一个会话,在浏览器中设置了 cookie,我成功登录了一个会话。
但是当用 Chrome 测试这个时,除了设置 cookie 的部分外,一切都完美无缺。我在一天的时间里对此进行了严格的测试,我可以跟踪 cookie 到它从后端发送的位置。但 Chrome 拒绝保存 cookie。
这是我用于维护会话的代码:
服务器/app.js
var store = new MongoDBStore({
uri: DB,collection: 'sessions'
});
// Catch errors
store.on('error',function (error) {
console.log(error);
});
app.use(require('express-session')({
secret: process.env.SESSION_SECRET,saveUninitialized: false,// don't create session until something stored
resave: false,//don't save session if unmodified
store: store,cookie: {
maxAge: parseInt(process.env.SESSION_LIFETIME),// 1 week
httpOnly: true,secure: !(process.env.NODE_ENV === "development"),sameSite: false
},}));
//Mongo Session Logic End
app.enable('trust proxy');
// 1) GLOBAL MIDDLEWARES
// Implement CORS
app.use(cors({
origin: [
process.env.CLIENT_ORIGINS.split(',')
],credentials: true,exposedHeaders: ['set-cookie']
}));
CLIENT_ORIGINS
设置为运行我的 React 客户端的 https://localhost:3000
和 http://localhost:3000
。
我尝试过的一些事情:
- 尝试
secure:true
和secure:false
的所有组合以及sameSite:false
和sameSite:'strict'
的所有组合 - 将域设置为
NULL
或空字符串 - 尝试随机更改路径
exports.signIn = async (req,res,next) => {
const { email,password } = req.body;
if (signedIn(req)) {
res.status(406).json('Already Signed In');
return;
}
const user = await User.findOne({ email: email });
if (!user) {
res.status(400).json('Please enter a correct email.');
return;
}
if (!(await user.matchPassword(password))) {
res.status(400).json('Please enter a correct password.');
return;
}
req.session.userId = user.id;
res.status(200).json({ msg: 'Signed In',user: user });
};
这是我用于使用 Axios 从 React 调用 API 的通用请求模型:
import axios from "axios";
import CONfig from "../Services/Config";
axios.defaults.withCredentials = true;
const SERVER = CONfig.SERVER + "/api";
let request = (method,extension,data = null,responseTypeFile = false) => {
//setting up headers
let config = {
headers: {
"Content-Type": "application/json",},};
// let token = localStorage["token"];
// if (token) {
// config.headers["Authorization"] = `Bearer ${token}`;
// }
//POST Requests
if (method === "post") {
// if (responseTypeFile) {
// config['responseType'] = 'blob'
// }
// console.log('request received file')
// console.log(data)
return axios.post(`${SERVER}/${extension}`,data,config);
}
//PUT Requests
else if (method === "put") {
return axios.put(`${SERVER}/${extension}`,config);
}
//GET Requests
else if (method === "get") {
if (data != null) {
return axios.get(`${SERVER}/${extension}/${data}`,config);
} else {
return axios.get(`${SERVER}/${extension}`,config);
}
}
//DELETE Requests
else if (method === "delete") {
if (data != null) {
return axios.delete(`${SERVER}/${extension}/${data}`,config);
} else {
return axios.delete(`${SERVER}/${extension}`,config);
}
}
};
export default request;
我测试过的更多东西:
- 我已经仔细检查了双方的凭据是否都设置为 true。
- 我已确保身份验证周期适用于其他浏览器。
- 当我在 http 而不是 https 上运行 React 时,我还确保身份验证周期在 Chrome 上工作
- 我还将我的自签名证书添加到本地计算机上的受信任根证书中。 Chrome 不再向我显示警告,但仍拒绝保存 cookie
- 如果我在禁用网络安全的情况下运行 Chrome 实例,我已确保身份验证周期有效。
- 我试图通过在地址栏中使用 127.0.0.1 而不是 localhost 来使其工作,但无济于事。
- 任何一方的控制台都没有记录任何错误。
任何和所有帮助将不胜感激
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。