IT Tech/vue.js

vue3 의 로그인 상태 관리, reactive - watchEffect

Developer JS 2024. 3. 5. 15:24
반응형

vue3를 사용해서 Admin 사용자의 관리 어플리케이션을 구현을 하고 있습니다. 기존에 사용하던 어플리케이션의 로그인 방식을 카카오 로그인과 구글 로그인 등 api를 통해서 구현했기 때문에 관리 어플리케이션도 동일하게 카카오 로그인등의 외부 인증 api를 통해서 로그인을 구현했습니다. 로그인을 성공한 후 전달받은 유저의 정보를 백엔드 api 어플리케이션으로 전달해서 해당 유저의 role을 전달받아서 관리 어플리케이션에서 관리자 이상의 등급을 가진 유저만 관리 어플리케이션에 접속 할 수 있게 하려고 합니다.

 

그러면 당연히 전달받은 유저의 role 값을 vue3 어플리케이션에서 유지하며, Router Guard를 통해서 role 검증을 한 후 이동 할 수 있게 해야합니다. 여기서 사용가능한 것이 reactive입니다.

 

Vue3 Composition API의 핵심 기능 'reactive'

Composition API의 핵심 기능중의 하나인 'reactive'는 객체를 반응형(reactive) 데이터로 만드는 데 사용되는데요. 반응형 데이터는 Vue 컴포넌트의 상태를 관리하는 데 사용되며, 해당 데이터의 변경사항이 자동으로 감지되어 Vue 컴포넌트가 적절히 업데이트 하게 됩니다.

 

import { reactive } from 'vue';

const userState = reactive({
    isAuthenticated: false,
    role: null
});

function setUserRole(role) {
    userState.role = role;
    userState.isAuthenticated = true;
}

function logout() {
    userState.role = null;
    userState.isAuthenticated = false;
}

export { userState, setUserRole, logout };

 

userState.role = loginResponse.data.role

 

위의 코드처럼 응답받은 데이터를 userState의 role에 대입하고,

 

  Router.beforeEach((to, from, next) => {
    const requiredRoles = to.meta.requiredRole;
    if (requiredRoles) {
      const userRole = userState.role; // 사용자 역할을 가져오는 함수 (예: ['user', 'admin'])
      const hasRequiredRole = requiredRoles.some(role => role == userRole);

      if (!hasRequiredRole) {
        // 역할이 충분하지 않다면 로그인 페이지로 리다이렉트
        next('/login-1');
      } else {
        next();
      }
    } else {
      next(); // 메타 정보에 requiredRoles가 없는 경우, 그냥 진행
    }
  })

 

Router.beforeEach 함수를 통해서 역할을 비교해서 해당 역할이 조건에 맞을때만 다음으로 넘어갈 수 있도록 해주면 사용자의 권한 검증을 할 수 있습니다. 

 

문제점

이렇게 하면 유저의 권한을 업데이트하고, 권한에 따라 화면에 이동할 수 있는지를 확인할 수 있는데요. 문제는 이렇게만 하면 브라우저에서 새로고침을 하는 순간 userState에 저장되어있는 값이 초기화가 되고, 새로고침을 할 때마다 새롭게 로그인을 해줘야하는 문제가 생깁니다. 뭐 어플리케이션의 보안 수준에 따라서 어떻게 할 지에 대한 결정이 되겠지만, 저는 지금 그 정도로 어플리케이션의 로그인을 바라지 않기 때문에 새로고침을 해도 값을 유지할 수 있도록 해 줄 것입니다.

 

watchEffect를 사용해서 userState의 값이 변경될때마다 localStorage에 userState의 값을 저장해주고, userState는 localStorage에 값이 존재하면 꺼내오고, 없다면 다른 기본값으로 세팅하는 방식으로 userState가 브라우저의 새로고침에도 값을 잃지 않고, 계속 유지 할 수 있도록 합니다.

 

import { reactive, watchEffect } from 'vue';

// Local Storage에서 상태를 읽어와 초기화합니다.
const initialState = JSON.parse(localStorage.getItem('userState')) || {
    isAuthenticated: false,
    role: null,
};

const userState = reactive(initialState);

// userState가 변경될 때마다 Local Storage에 저장합니다.
watchEffect(() => {
    localStorage.setItem('userState', JSON.stringify(userState));
});

function setUserRole(role) {
    userState.role = role;
    userState.isAuthenticated = true;
}

function logout() {
    userState.role = null;
    userState.isAuthenticated = false;
}

export { userState, setUserRole, logout };

 

이렇게 하면, 브라우저가 새로고침 되더라도, 로그인 했던 role이 값을 잃지 않고 사용할 수 있게 됩니다. 

반응형