Best practices to sync the client side vuex state to the server side state?

Viewed 1076

I have cloned vue-hackernews-2.0, a Vue.js app with SSR and vuex.

This app listens on port 8080, while my api server listens on 3000 in my local dev environment.I am trying to implement user authentication in it, using jwt.

when the client recieves the token from api server,the client state updates with the token, But How do I make the server side state aware that the user is logged in ?

In general, how to sync client side and server side state?

An ugly hack I thought of is that when the user logs in with correct credentials, the api server should open a socket connection with the 8080 server and trigger a state update on server side? Is it an acceptable/scalable solution? What are the best practices regarding this?

MORE DETAILS.. (a) in router I implemented the navigation guard :

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

Now on login in my Login page, I post an action to my api server (NOT the vue server on port 8080) , and store the token in client side state. But when I reload the logged in dashboard page, it can't find the token on server side state, the function isLoggedIn above returns false, and it tries to render the login page please see the code above, the client side DOM thus doesn't match the server rendered page, and client tries to re-render the DOM on client side.

1 Answers

Well, you wrote you're using jwt.

So the server doesn't need to know if the user is logged in.

As long as the client provides this jwt on every request (header, cookie, (body)), the server can authorize these requests.

To proper handle jwt, you could use the npm package:

const JWT = require('jsonwebtoken')

Issuing a token:

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

Middleware to validate the token:

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')  
}
Related