将客户端 vuex 状态同步到服务器端状态的最佳实践?

Posted

技术标签:

【中文标题】将客户端 vuex 状态同步到服务器端状态的最佳实践?【英文标题】:Best practices to sync the client side vuex state to the server side state? 【发布时间】:2019-11-04 22:55:33 【问题描述】:

我已经克隆了vue-hackernews-2.0,这是一个带有 s-s-r 和 vuex 的 Vue.js 应用程序。

这个应用程序listens on port 8080,而我的 api 服务器在我的本地开发环境中侦听 3000。我正在尝试使用 jwt 在其中实现用户身份验证。

当客户端从 api 服务器收到令牌时,客户端状态会随着令牌更新,但是 如何让服务器端状态知道用户已登录

一般来说,如何同步客户端和服务器端的状态?

我想到的一个丑陋的 hack 是,当用户使用正确的凭据登录时,api 服务器应该打开与 8080 服务器的套接字连接并在服务器端触发状态更新?这是一个可接受/可扩展的解决方案吗? 这方面的最佳实践是什么?

更多详情.. (a) 在路由器中我实现了导航守卫:

      ....
      if (router.app.$store.getters.isLoggedIn)  next()
      else  next('/login')
      ...

现在在我的登录页面登录时,我将一个操作发布到我的 api 服务器(不是端口 8080 上的 vue 服务器),并将令牌存储在客户端状态。 但是当我重新加载登录的仪表板页面时,它在服务器端状态下找不到令牌,上面的函数isLoggedIn返回false,并尝试渲染登录页面请参见上面的代码,因此客户端 DOM 与服务器呈现的页面不匹配,客户端尝试在客户端重新呈现 DOM。

【问题讨论】:

【参考方案1】:

嗯, 你写你正在使用jwt。

所以服务器不需要知道用户是否登录。

只要客户端在每个请求(header、cookie、(body))上提供这个jwt,服务器就可以授权这些请求。

要正确处理jwt,您可以使用npm 包:

const JWT = require('jsonwebtoken')

发行代币:

const token = JWT.sign(
    userId: user.id,
    moreData: undefined,
  ,
   'somRandomLongPrivateKey123', // protect it, env var?
  
    expiresIn: '2d',
  )

验证令牌的中间件:

module.exports = async (req, res, next) => 
try 
  const payload = JWT.verify(token, 'yourprivatekey') 
  req.user = User.find(payload.userId) 

  next()

 catch(e) 
  return res.status(401).send('no valid token')  

【讨论】:

问题是:一般来说,如何同步客户端和服务器端的状态?我应该在哪里验证并在 s-s-r 服务器或后端服务器上生成上述 JWT?事实上,这个问题有点复杂。请尝试了解更多详细信息。无论如何感谢您的回答。 我找到了解决方案。如果有人需要,我可以写一个详细的答案并且面临着我所面临的同样奇怪的问题.. :) @RameshPareek 如果你有一个详细的答案,发布一个详细的答案总是一个好主意 - 我想看看。 @Brent,是的,我确实有,实际上我花了很长时间才实现这一目标,我一生都无法忘记那一周,但是我可以理解 vue 的一些内部工程js 工作。人们说 vuejs 文档很好,但我认为文档中没有提到这一点。在服务器端渲染时如何管理用户的登录状态。我很快就会在媒体上发表一篇关于这个的好文章。

以上是关于将客户端 vuex 状态同步到服务器端状态的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 vuex 和 vue-router 在后端和前端之间同步状态?

反应初始化和与后端同步状态

vuex中为啥更新其中一个状态的值还能同步更新另一个状态的

Vuex 状态与 Firebase 同步

像 next.js 这样的服务器端渲染中状态管理的最佳方法是啥?

Vue笔记(Vuex全局状态管理器)