node.js 服务器上的用户会话未更新

User session not updating on node.js server

我目前正在努力让用户的会话根据客户端的更新请求进行更新。这里的思路是更新成功后,立即将更新后的用户数据展示给Client。为此,我使用会话来存储数据,而不必在每次刷新时都向数据库发出获取请求。

我的问题是,每当用户更新自己时,会话仍然保留登录后检索到的先前值,尽管我将其设置为新值。所以 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);
      }
    );
   }

问题

上面的代码,虽然在混合使用 server-side sessions 和 client-side sessions (JWTs) 的方式上有点不寻常,但并不是不正确的或损坏。

本例中的问题出在 client-side,处理 cookie 的方式 - 这意味着更新似乎没有应用于 session 数据。

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

解决方案

Axios 正被用于在 client-side 上发出请求,请求未使用适当的 cookie header 发送。

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

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