在我的 Node.js 后端应用程序中,我尝试使用 Express 并保存电子邮件来识别用户是否已登录以及我应该引用哪个帐户。
但是,在切换一些 cookie 设置以考虑 HTTPS 和本地开发之后,突然间,该字段不再存在于安全环境中。
(对于其他上下文,我在 React.js 中使用 axios 作为前端来进行 API 调用。)
req.session.save()
对我没有好处。
我仔细检查了凭据是否正在发送,并且我使用的 axios 应用程序已将
withCredentials
设置为 true
。
我还查看了 MongoDB 存储,发现该字段不会出现在安全上下文中,但出于某种原因,它有时会出现在不安全上下文中。这可能是一个错误,如果是,请告诉我。 Cookie 在所有情况下都存在。
这是我的参考代码(我省略了我认为不相关的部分。)
(客户端.jsx,前端)
axios.defaults.withCredentials = true
const client = axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL, // "http://localhost:8080",
headers: {
},
responseType: 'json'
});
(服务器.js,后端)
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const { uri, ss, initial } = require('./src/api/config/config');
const fifteen_min = 15 * 60 * 1000;
const store = new MongoDBStore({
uri: uri,
collection: 'sessions',
expires: fifteen_min,
connectionOptions: { useNewUrlParser: true, useUnifiedTopology: true }
});
const insecure_setting = {
secret: ss,
cookie: {
maxAge: fifteen_min,
secure: false,
httpOnly: true,
},
store: store
}
const secure_setting = {
secret: ss,
cookie: {
maxAge: fifteen_min,
secure: true,
httpOnly: true,
sameSite: 'none',
},
store: store
}
const sess = process.env.MODE === "prod" ? secure_setting : insecure_setting;
app.use(session(sess));
/* ... */
app.use('/session',cors(corsOptions), requireAuth, sessionPriv);
(端点内;sessionpublic.js;后端)
if (msg !== "Successful login.") {
body = {
msg: msg,
success: false
}
res.send(body);
return;
}
req.session.email = fields['email'];
req.session.save();
console.log(req.session); // 'email' is included here!
(permissions.js;后端)
function requireAuth (req, res, next) {
console.log(req.session.email); // undefined in secure contexts!
if (!req.session || !req.session.email) {
console.log("redirect made.");
/* redirecting code */
res.send();
return;
} else {
req.session.foobar = Date.now();
req.session.touch();
next();
}
}
我已在安全设置中设置了
saveUninitialized: true
。也没有用。
如果您有任何问题,我会尽力解答。预先感谢您!
====================== 为了展示此行为的实际效果,以下是我的 AWS Beanstalk 应用程序的输出日志。
Sep 22 12:51:32 ip-172-31-7-83 web[295290]: Origin received: incoming from https://frontend.com
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: Origin received: incoming from https://frontend.com
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: login try in progress.
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: Session {
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: cookie: {
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: path: '/',
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: _expires: 2023-09-22T13:06:33.056Z,
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: originalMaxAge: 900000,
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: httpOnly: true,
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: secure: true,
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: sameSite: 'none',
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: saveUninitialized: true
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: },
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: email: '[email protected]'
Sep 22 12:51:33 ip-172-31-7-83 web[295290]: }
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: Origin received: incoming from https://frontend.com
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: Origin received: incoming from https://frontend.com
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: undefined
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: Session {
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: cookie: {
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: path: '/',
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: _expires: 2023-09-22T13:06:34.430Z,
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: originalMaxAge: 900000,
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: httpOnly: true,
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: secure: true,
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: sameSite: 'none',
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: saveUninitialized: true
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: }
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: }
Sep 22 12:51:34 ip-172-31-7-83 web[295290]: redirect made.
只是更新。我做了一些版本回滚到一个正在运行的版本,我发现一行代码被意外删除。
阅读这段代码解决了我的问题。
if (process.env.MODE === "prod") {
app.set('trust proxy', 1);
}
这可能是一个问题,因为前端和后端 API 在不同的应用程序中工作,因此我们需要此设置以使它们正确交互。