【问题标题】:User session not updating on node.js server用户会话未在 node.js 服务器上更新
【发布时间】: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


【解决方案1】:

问题

上面的代码虽然混合使用服务器端会话和客户端会话 (JWT) 的方式有点不寻常,但它并没有不正确或损坏。

在这种情况下,问题出在客户端,即处理 cookie 的方式 - 这意味着更新似乎没有应用于会话数据。

服务器已正确设置会话 cookie,并已被客户端接受,但未包含在进一步的请求中。这意味着未来的请求似乎具有不正确的会话数据,因为服务器将每个请求视为一个全新的请求,而没有先前存在的会话。 这个事实被隐藏了,因为 JWT 被用来验证用户是否登录,而不是检查服务器端会话。

解决方案

Axios 被用于在客户端发出请求,请求未使用适当的 cookie 标头发送。

要解决此问题,应为每个请求提供 withCredentials 选项,如下所示:

Axios.patch(address, data, { withCredentials: true }).then(handleResponse);

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 1970-01-01
    • 2020-02-07
    • 2016-01-18
    • 2011-07-14
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多