programing

Vue 경로가 확인되기 전에 Vuex 액세스

goodjava 2022. 11. 10. 20:52

Vue 경로가 확인되기 전에 Vuex 액세스

입수 내용:

  1. 라우터(auth-required 루트 및 퍼블릭루트 포함)
  2. vuex(사용자 인증 상태 포함)

원하는 항목: 다음을 사용하여 서버에 요청 전송axios앱을 로드하기 전에(라우터가 해결되기 전에) 사용자의 인증 상태를 확인합니다.

router.js:

import Vue from 'vue'
import Router from 'vue-router'
import store from './store'

Vue.use(Router)

const router = new Router({
  ...
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/account',
      name: 'account',
      component: () => import(/* webpackChunkName: "account" */ './views/Account.vue'),
      meta: {
        requiresAuth: true
      }
    }
  ]
})

router.beforeEach((to, from, next) => {
  if (to.matched.some(route => route.meta.requiresAuth)) {
    if (store.state.authStatus)
      next()
    else
      next({name: 'home'})
  } else {
    next()
  }
})

export default router

store.js:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    authStatus: false
  },
  mutations: {
    setAuthStatus(state, authStatus) {
      state.authStatus = authStatus
    }
  }
})

 axios.get(...)
   .then(response => {
     store.commit('setAuthStatus', true)
   })

export default store

main.js:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

문제: 들어갈 때mydomain.com/acount(애플리케이션은 이전에 로드되지 않았습니다)로 리다이렉트 되었습니다.home. 리다이렉트 후 승인되었음을 확인합니다(Home 컴포넌트 내에 일부 DOM 요소를 설정했습니다.이 요소는 인증된 사용자에게만 표시됩니다.


나도 해봤지만 도움이 안 됐어

store.js:

const store = new Vuex.Store({
  ...
  actions: {
    setAuthStatus({commit}) {
      axios.get(...)
        .then(response => {
          commit('setAuthStatus', true)
        })
    }
  }
})

main.js:

store.dispatch('setAuthStatus').then(() => {
  new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount('#app')
})

편집: inmain.js나는 가려고 했다.

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

로.

new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app')

그것도 도움이 안 됐어요

Vanojx1의 답변을 바탕으로 다음 방법으로 문제를 풀었습니다.

store.js:

const store = new Vuex.Store({
  state: {
    authStatus: axios.get(...).then(response => {
      store.commit('setAuthStatus', true)
    }),
    userAuth: false
  },
  mutations: {
    setAuthStatus(state, authStatus) {
      state.userAuth = authStatus
    }
  }
})

router.js:

router.beforeEach((to, from, next) => {
  if (to.matched.some(route => route.meta.requiresAuth)) {
    store.state.authStatus.then(() => {
      //we're getting 200 status code response here, so user is authorized
      //be sure that API you're consuming return correct status code when user is authorized
      next()
    }).catch(() => {
      //we're getting anything but not 200 status code response here, so user is not authorized
      next({name: 'home'})
    })
  } else {
    next()
  }
})

네비게이션 가드에서는 비동기적인 것이 필요하기 때문에 authStatus로 저장해 둡니다.해결되면 커밋 및 로그 설정인 스테이터스.네비게이션 가드에서는 약속이 해결될 때까지 기다렸다가 다음 함수를 호출하여 다음 라우터에 들어갑니다.

Store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    /*  EXAMPLE
    authStatus: new Promise(resolve => {
      setTimeout(() => {
        const requestResult = true;
        store.commit("setAuthStatus", requestResult);
        resolve(requestResult);
      }, 1000);
    }),
    */
    authStatus: axios.get(...).then((requestResult) => {
        store.commit("setAuthStatus", requestResult);
    }),
    loggedIn: false
  },
  mutations: {
    setAuthStatus(state, loggedIn) {
      state.loggedIn = loggedIn;
    }
  }
});

export default store;

router.displaces

router.beforeEach((to, from, next) => {
  if (to.matched.some(route => route.meta.requiresAuth)) {
    store.state.authStatus.then(loggedIn => {
      if (loggedIn) next();
      else next({ name: "home" });
    });
  } else {
    next();
  }
});

이 솔루션이 여기서 작동하는지 확인합니다.

이 문제는 https://example.com/account 라는 URL을 입력하면 발생할 수 있습니다.

앱을 시작하고 Axios가 서버에 대한 비동기 요청을 수행합니다.그러니까 각자 이전부터 공리적인 통화를 해보는 게 좋을 것 같아요

이렇게 하면 사용자 인증에 문제가 없습니다.

문제는 공리를 동기화할 수 없기 때문에 공리와의 약속을 되돌려야 기능을 얻을 수 있다는 것입니다.

혹시 도움이 되셨다면 말씀해주세요.

언급URL : https://stackoverflow.com/questions/52420374/access-vuex-before-vue-route-is-resolved