반응형
문제 상황
Vuex로 클라이언트의 인증 상태를 관리한다. 메인 페이지로 사용하는 컴포넌트에서 로그인 한 사용자와 로그인 하지 않은 사용자에게 보여주는 컴포넌트를 분리했는데, 페이지를 새로고침 하면 인증 상태가 초기화될 때 잠깐 LoginBefore 컴포넌트가 그려지고, 서버에 인증 상태를 확인하는 요청이 완료되고 나면 LoginAfter 컴포넌트가 그려져서 깜박이게 된다.
<MainComp>
<LoginBefore v-if=!store.get.auth>
</LoginBefore>
<LoginAfter v-if=store.get.auth>
</LoginAfter>
</MainComp>
해결 방법
컴포넌트가 그려지기 전에 인증 상태를 확인해야 한다.
방법1 컴포넌트 로딩 시점보다 빠르게 인증을 받아내기
브라우저가 새로고침되면 컴포넌트보다 먼저 뷰 라우터의 네비게이션 가드가 실행되므로 이때 인증을 받아낸다.
장점
- 명확한 타이밍에 인증을 받을 수 있다.
단점
- 모든 라우팅에 대해서 세션을 체크하기 때문에 불필요한 API 호출이 생긴다.
- 인증 함수를 동기적으로 호출하기 때문에 지연이 발생할 수 있다.
router.beforeEach(async (to, from, next) => {
await checkSession()
if (to.meta.requiresAuth && !store.getters.isAuthenticated) {
next({path: '/'}) // 권한이 없을 경우 메인으로 리다이렉트
} else {
next() // 권한이 있다면 라우트 이동
}
})
방법2 새로고침해도 인증 상태가 초기화되지 않게 만들기
LocalStorage나 SessionStorage에 Vuex의 상태를 연동해서 새로고침 했을 때, store가 초기화되는 시점에 값을 불러오면 상태를 계속 유지할 수 있다.
장점
- 필요한 상태를 간단하게 계속 유지할 수 있다.
단점
- 상태가 보안상 중요한 것이라면 LocalStorage나 SessionStorage는 적절하지 않다.
- 세션이 사라져도 LocalStorage에 데이터가 남아 있으면 인증된 상태로 남는다.
plugins: [
store => {
if (localStorage.getItem('store')) {
const storedState = JSON.parse(localStorage.getItem('store'));
store.replaceState(storedState);
}
store.subscribe((mutation, state) => {
localStorage.setItem('store', JSON.stringify(state));
})
}
]
결론
인증의 정확도를 위해서 방법1을 선택했다. 세션 쿠키는 브라우저가 종료될 때 같이 만료되는데 로컬 스토리지는 계속 남기 때문에 세션이 정말 유효한지 확인하기 어렵다고 생각했다.
반응형
'Trouble shooting' 카테고리의 다른 글
NGrinder Controller Local IP Address 설정 문제 (0) | 2024.02.03 |
---|---|
[문제 해결] Entity 3개가 1:N-1:N 관계일 때, 최상위 Entity와 연관된 엔티티 조회할 때 N+1 문제 해결 (0) | 2024.01.03 |