Vuejs ssr check user is authenticated for each req

2019-08-21 08:49发布

问题:

I’m using this ssr boilerplate for my app, https://github.com/vuejs/vue-hackernews-2.0

I don’t know how to implement logic for checking is user authenticated for each user’s page request, I’m using cookies for storing user's token

I looked that router can handle request before render component:

  router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
      // this route requires auth, check if logged in
      // if not, redirect to login page.
      // isLoggedIn()
      //   .then(response => response.json())
      //   .then(json => {
      //     console.log(json[0])
      //     next()
      //   })
      //   .catch(error => {
      //     console.log(error)
      //     next()
      //   })

      const x = true

      if (!x) {
        next({
          path: '/signin',
          query: { redirect: to.fullPath }
        })
      } else {
        next()
      }
    } else {
      next() // make sure to always call next()!
    }
  })

  return router
}

But here is problem, router starting to use this code in client-side and in server-side, which in my case a little bit incorrect.

How to send request for is user authenticated only once, or in client-side or in server-side?

回答1:

Answering on my issue, next approach - is what I searched, this vue router middleware will check user, before sending other requests(in my components methods like asyncData), then put user's info into store:

// router/index.js

export function createRouter (cookies) {
  const router = new Router({ ... })

  router.beforeEach((to, from, next) => {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (to.matched.some(record => record.meta.requiresAuth)) {
      if (router.app.$store) {
        router.app.$store
          .dispatch('FETCH_CURRENT_USER', cookies)
          .then(next)
          .catch(() => next('/signin'))
      } else {
        next()
      }
    } else {
      next()
    }

    return router
}

// store/actions.js

export default {
  FETCH_CURRENT_USER: ({ commit }, cookie) => {
    const values = {
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json',
        Origin: FRONTEND_HOST,
        Cookie: cookie
      }
    }

    return fetch(`${API_HOST}/api/v1/users/me`, values)
      .then(handleStatus)
      .then(handleJSON)
      .then(json => commit('SET_CURRENT_USER', json))
  }
}