【发布时间】:2022-02-17 00:32:22
【问题描述】:
我目前正在努力让用户的会话在客户端发出更新请求后进行更新。这里的想法是在更新成功后立即将更新的用户数据显示给客户端。为此,我使用会话来存储数据,而不必每次刷新都向数据库发出 get-request。
我的问题是,每当用户更新自己时,会话仍然保持登录后检索到的先前值,尽管我将其设置为新值。所以 updateMyProfile 请求不会保存会话中的数据。这是我在刷新时调用的 Authenticate 请求测试的内容,以检索 currentUser 的用户数据
/服务器
app.use(
session({
key: "someID",
secret: "someSecret", //Normally this has to be long and complex for security
resave: false,
rolling: true,
saveUninitialized: false,
cookie: { //How long will the cookie live for?
expires: 60 * 60 * 1000, //Expires after one hour
}
}));
app.patch('/updateMyProfile', verifyJWT, async(req, res) => {
const name = req.body.name;
const email = req.body.email;
const phoneNr = req.body.phoneNr;
const id = req.body.id;
var updated = "UPDATE users set name = ?, email = ?, phoneNr = ? WHERE id = ?;";
var retrieved = "SELECT * FROM users WHERE id = ?;";
db.query(updated, [name, email, phoneNr, id],
(err, result) => {
if (err) {
res.send({message: err}) //Sending error to front-end
console.log(err);
}
if (result) {
db.query(retrieved, id,
(err, resultRetrieved) => {
if (err) {
res.send({message: err}) //Sending error to front-end
console.log(err);
} else {
req.session.user = resultRetrieved; //Session is updated to contain new data!
res.send({user: resultRetrieved, message: "Update succesful!"});
console.log("User is now: " + req.session.user[0].name);
res.end();
}
})}
});
});
//通过UseEffect函数在客户端每次刷新时调用该方法
app.post('/authenticate', (req, res) => { //An endpoint for user-auth
const token = req.body.token;
const userSession = req.session.user;
jwt.verify(token, "jwtSecret", (err, decoded) => {
if (err) {
res.send({auth: false, user: "No valid token!"});
console.log('No valid token');
}
else if (userSession) { //Verified user! < ----------------->
res.send({auth: true, user: userSession});
console.log(userSession[0].name + ' is in!');
}
else { //Else if user is not verified, we return an empty object with rejected authentication
res.send({auth: false, user: 'No user session!'});
console.log('No user session');
}
})
});
这是来自客户端的更新请求示例
const update = () => {
Axios.patch("http://localhost:3001/updateMyProfile", {name: name, email: email, phoneNr: phoneNr, id: id},
{headers: {"x-access-token": localStorage.getItem("token")}}
).then(
(response) => {
alert(response.data.message);
}
);
}
【问题讨论】:
-
使用“console.log("User is now: " + req.session.user[0].name);" 输出新用户详细信息时显示的结果是什么?
-
为什么要将会话设置为包含一组用户,而不仅仅是您需要的用户信息?我认为这与您的问题无关,我只是好奇。
-
您的“updateMyProfile”端点从我在这里看到的非常危险。如果我被认证为 userID 1,我可以向 /updateMyProfile 发出 PUT 请求并传入 userID 2,您的系统不仅会使用我选择的任何内容更新该用户,而且还会将我的会话切换到该用户。这实际上是帐户接管。您必须记住检查 JWT 上的 ID 是否与我尝试修改的帐户的 ID 相同。某种访问控制系统需要在这里实现
-
@Dutchman 感谢您的回复 1) req.session.user[0].name 的值是用户的更新名称。所以有趣的是,它实际上捕获了新数据,但在刷新到会话时并没有将其保存。 2) 我在哪里设置会话以包含一组用户?据我所见,它应该只是一个特定的行,因为它在数据库中的“id”上的索引。 3)谢谢,我看到了那里的问题,肯定要在那个端点方法中加入一个检查功能你对会话没有保存新添加的数据的原因有任何线索吗?
标签: javascript node.js reactjs express session