로컬 스토리지에서 Vuex Store를 복원하기 전에 미들웨어 실행
nuxtjs 프로젝트에서 페이지를 보호할 인증 미들웨어를 만들었습니다.vuex-displaystate(vuex-display 및 nuxt-vuex-display도 시도)를 사용하여 vuex 스토어를 유지합니다.
페이지 간을 이동할 때는 모든 것이 정상적으로 작동하지만 페이지를 새로 고치거나 보호된 경로에 직접 착지하면 로그인 페이지로 리디렉션됩니다.
localStorage 플러그인
import createPersistedState from 'vuex-persistedstate'
export default ({ store }) => {
createPersistedState({
key: 'store-key'
})(store)
}
인증 미들웨어
export default function ({ req, store, redirect, route }) {
const userIsLoggedIn = !!store.state.auth.user
if (!userIsLoggedIn) {
return redirect(`/auth/login?redirect=${route.fullPath}`)
}
return Promise.resolve()
}
vuex-persist 플러그인 대신 이 플러그인 vuex-persistedstate를 사용하여 이 문제를 해결했습니다.vuex-persist에 버그(또는 설계 아키텍처)가 있는 것 같습니다.
Current 접근 방식으로는 항상 실패할 것입니다.
실제 문제는 Vuex Store를 서버 측 Vuex Store와 동기화할 수 없다는 것입니다.
실제로는 클라이언트 및 서버(토큰)와 동기화하는 데이터 문자열만 필요합니다.
쿠키와의 동기화를 실현할 수 있습니다.왜냐하면 쿠키는 브라우저의 모든 요청에 자동으로 전달되기 때문입니다.따라서 어떤 요청도 설정할 필요가 없습니다.브라우저 주소 표시줄에서 URL을 누르거나 탐색을 통해 URL을 누릅니다.
쿠키 세트 및 제거에는 'cookie-universal-nuxt' 모듈을 사용할 것을 권장합니다.
로그인 후 쿠키 설정
this.$cookies.set('token', 'Bearer '+response.tokens.access_token, { path: '/', maxAge: 60 * 60 * 12 })
로그아웃 시 쿠키 삭제용
this.$cookies.remove('token')
이해를 돕기 위해 문서를 검토하십시오.
또한 API 요청에 @nuxt/http 모듈을 사용하고 있습니다.
nuxt에는 vuex 스토어 인덱스 파일에 nuxtServerInit()라는 함수가 있습니다.이 명령을 사용하여 요청에서 토큰을 가져와 http 모듈헤더로 설정해야 합니다.
async nuxtServerInit ({dispatch, commit}, {app, $http, req}) {
return new Promise((resolve, reject) => {
let token = app.$cookies.get('token')
if(!!token) {
$http.setToken(token, 'Bearer')
}
return resolve(true)
})
},
아래는 저의 Nuxt 페이지 레벨 미들웨어입니다.
export default function ({app, req, store, redirect, route, context }) {
if(process.server) {
let token = app.$cookies.get('token')
if(!token) {
return redirect({path: '/auth/login', query: {redirect: route.fullPath, message: 'Token Not Provided'}})
} else if(!isTokenValid(token.slice(7))) { // slice(7) used to trim Bearer(space)
return redirect({path: '/auth/login', query: {redirect: route.fullPath, message: 'Token Expired'}})
}
return Promise.resolve()
}
else {
const userIsLoggedIn = !!store.state.auth.user
if (!userIsLoggedIn) {
return redirect({path: '/auth/login', query: {redirect: route.fullPath}})
// return redirect(`/auth/login?redirect=${route.fullPath}`)
} else if (!isTokenValid(store.state.auth.tokens.access_token)) {
return redirect({path: '/auth/login', query: {redirect: route.fullPath, message: 'Token Expired'}})
// return redirect(`/auth/login?redirect=${route.fullPath}&message=Token Expired`)
} else if (isTokenValid(store.state.auth.tokens.refresh_token)) {
return redirect(`/auth/refresh`)
} else if (store.state.auth.user.role !== 'admin')
return redirect(`/403?message=Not having sufficient permission`)
return Promise.resolve()
}
}
코드와 같이 토큰 소스가 다른 에 대해 다른 조건을 씁니다.서버 프로세스에서는 cookie에서 토큰을 얻고 클라이언트는 token store에서 토큰을 가져옵니다.(여기에서는 cookie에서도 얻을 수 있습니다)
그 후 레이아웃의 스토어 데이터 바인딩으로 인해 약간의 수화 문제가 발생할 수 있습니다.이 문제를 해결하려면<no-ssr></no-ssr>
이러한 유형의 템플릿 코드를 래핑합니다.
언급URL : https://stackoverflow.com/questions/54789823/middleware-executing-before-vuex-store-restore-from-localstorage
'programing' 카테고리의 다른 글
섹션과 태스크 openmp의 차이 (0) | 2022.08.14 |
---|---|
...vue.js의 mapState SyntaxError(vuex 사용) (0) | 2022.08.14 |
C, C++, Java 및 C#에서의 사전 및 사후 증분 연산자 동작 (0) | 2022.08.14 |
VueJs: 텍스트 영역 입력 바인딩 (0) | 2022.08.14 |
Nuxt VueJ에서 직접 소품 변환 방지 (0) | 2022.08.13 |