import { createWebHistory, createRouter } from "vue-router"; import store from "./AppStore"; import filters from '../common/filters'; // 메인화면 import Main from "./user/portal/main/Main.vue"; // 관리자 import CommonSelectList from "./adm/boardManagement/template/commonTemplate/CommonSelectList.vue"; import CommonSelectListOne from "./adm/boardManagement/template/commonTemplate/CommonSelectListOne.vue"; const beforeRoutes = [ /* 메인화면 */ { path: "/", name: "main", korName: "홈", component: Main }, // 관리자 { path: "/adm", children: [ { path: "commonSelectListOne.page", name: "CommonSelectListOne", korName: "", component: CommonSelectListOne }, { path: "commonSelectList.page", name: "CommonSelectList", korName: "", component: CommonSelectList }, ], }, ]; import { findAll, accessCheck } from "../../resources/api/router"; import { getCntxtPth } from "../../resources/api/cntxtPth"; import { save } from "../../resources/api/cntnStats"; import { mdiConsoleLine } from "@mdi/js"; // Context Path 정보 호출 async function getContextPath() { try { const res = await getCntxtPth(); if (res.status == 200) { let ctx = res.data.data || ''; // Context Path 정보 if(ctx == '/') { ctx = ''; // Context Path가 '/'인 경우 빈 문자열로 설정 } store.commit("setContextPath", ctx); // Context Path 정보 저장 return ctx; }else { store.commit("setStoreReset"); window.location = filters.ctxPath('/') } } catch (error) { return []; } } // 라우터 정보 호출 async function fetchRoutes() { try { const res = await findAll(); if (res.status == 200) { const newRoutes = res.data.data.map(route => ({ path: route.pageCrs, name: route.contsEngNm, korName: route.contsKornNm, component: () => import(`${route.compnCrs}`), meta: { authrt: route.authrtList, typeId: route.contsId, korName: route.contsKornNm } })); return newRoutes; }else { store.commit("setStoreReset"); window.location = filters.ctxPath('/') } } catch (error) { return []; } } // Context Path를 라우터에 추가하는 함수 function addContextPathToRoutes(routes, contextPath) { return routes.map(route => { const newRoute = { ...route, path: contextPath + route.path }; // if (route.children && route.children.length > 0) { // newRoute.children = addContextPathToRoutes(route.children, contextPath); // } return newRoute; }); } // 접근 제어 확인 async function accessUrl(path) { try { const res = await accessCheck({ path: path }); if (res.status == 200) { return res.data.data; } } catch (error) { return false; } } // 사용자 권한과 라우터에 포함되어 있는 권한을 비교하여 최종 권한 추출 function mergeAuth(userRoles, routeMeta) { const result = { inqAuthrt: 'N', // 읽기 권한 regAuthrt: 'N', // 쓰기 권한 mdfcnAuthrt: 'N', // 수정 권한 delAuthrt: 'N', // 삭제 권한 fileDwnldAuthrt: 'N', // 파일 다운로드 권한 }; if (!routeMeta || !routeMeta.authrt || routeMeta.authrt.length === 0) { return result; } routeMeta.authrt.forEach(auth => { if (userRoles.includes(auth.authrtCd)) { if (auth.inqAuthrt === 'Y') result.inqAuthrt = 'Y'; if (auth.regAuthrt === 'Y') result.regAuthrt = 'Y'; if (auth.mdfcnAuthrt === 'Y') result.mdfcnAuthrt = 'Y'; if (auth.delAuthrt === 'Y') result.delAuthrt = 'Y'; if (auth.fileDwnldAuthrt === 'Y') result.fileDwnldAuthrt = 'Y'; } }); return result; } // 통계 등록 async function cntnStatsSave(typeId, roles) { try { const cntnStats = { 'typeId': typeId, 'mbrAuthList': roles } await save(cntnStats); } catch (error) { } } // 권한 검증 function isValidRole() { const roles = store.state.roles; if (!Array.isArray(roles)) { store.commit("setStoreReset"); return false; } for (const role of roles) { if (typeof role !== 'object' || !role.hasOwnProperty('authority')) { store.commit("setStoreReset"); return false; } } return true; } export default async function createAppRouter() { const ctx = await getContextPath(); // DB에 적재된 Context Path 정보 호출 const dynamicRoutes = await fetchRoutes(); // DB에 적재된 라우터 정보 호출 const prefixedBeforeRoutes = addContextPathToRoutes(beforeRoutes, ctx); // 기존 라우터 정보에 Context Path 추가 const prefixedDynamicRoutes = addContextPathToRoutes(dynamicRoutes, ctx); // DB에 적재된 라우터 정보에 Context Path 추가 console.log('prefixedDynamicRoutes: ', prefixedDynamicRoutes); const newRoutes = prefixedBeforeRoutes.concat(prefixedDynamicRoutes); // 기존 라우터 정보와 합치기 console.log('newRoutes: ', newRoutes); const AppRouter = createRouter({ history: createWebHistory(), routes: newRoutes, }); AppRouter.beforeEach(async (to, from, next) => { const contextPath = store.state.contextPath; // Context Path 정보 const routeExists = AppRouter.getRoutes().some(route => route.path === to.path || (route.name && route.name === to.name)); if (!routeExists) { next({ name: 'notfound' }); return; } // 로그인 모드 확인 (JWT 또는 SESSION) const loginMode = store.state.loginMode || 'J'; // 기본값으로 JWT 설정 // console.log('loginMode', loginMode) // 로그인 상태 확인 (JWT 또는 SESSION) const isLogin = loginMode === 'J' ? store.state.authorization : store.state.mbrId; if (!isLogin && to.path !== filters.ctxPath('/login.page')) { sessionStorage.setItem('redirect', to.fullPath); next({ path: filters.ctxPath("/login.page") }); return; } // 접근 제어 확인 const accesCheck = await accessUrl(to.path); const roleCheck = isValidRole(); if (!accesCheck || !roleCheck) { alert('접근이 불가합니다.\n관리자에게 문의하세요.'); next(filters.ctxPath('/')); } // 경로에 따른 사용자 타입 설정 if (to.path === filters.ctxPath('/')) { store.commit('setUserType', 'portal') } else if (to.path.startsWith(filters.ctxPath('/adm'))) { store.commit('setUserType', 'adm'); } if (to.path === filters.ctxPath('/login.page')) { store.commit('setPath', to.path); next(); return; } const mbrAuth = store.state.roles.map(auth => auth.authority); // 사용자 권한 정보 const pageAuth = mergeAuth(mbrAuth, to.meta); sessionStorage.setItem("redirect", to.fullPath); // 메인 페이지 or 로그인 페이지 if (to.path === filters.ctxPath('/') || to.path.includes('/login.page') || to.path.startsWith(filters.ctxPath('/cmmn/')) || to.path.includes('/searchId.page') || to.path.includes('/resetPswd.page')) { let path = to.path; // 게시판일 경우 .page로 끝나는 경로가 있으므로 마지막 '/' 이전 경로로 설정 if (to.path.includes('BBS_MNG')) { let logicalPath = to.path; // context path 제거 if (contextPath !== '/' && logicalPath.startsWith(contextPath)) { logicalPath = logicalPath.substring(contextPath.length); } const lastSlashIndex = logicalPath.lastIndexOf('/'); // 마지막 '/' 인덱스 path = logicalPath.substring(0, lastSlashIndex); // 마지막 '/' 이전 경로 } store.commit('setPath', path); store.commit('setPageAuth', pageAuth); if (path.includes('/main.page')) { await cntnStatsSave(null, mbrAuth); // 메인 페이지 접속 시 사용자 접속 통계 증가 } next(); } else if (isLogin) { // 로그인 상태이고, 권한이 허용인 경우 검사 // const hasAcc = true; const hasAcc = to.matched.some(record => { if (!record.meta.authrt) return false; return record.meta.authrt.some(auth => { // 경로별 권한 검사 if (to.path.includes('/list.page')) { // 목록 권한 검증 return mbrAuth.includes(auth.authrtCd) && auth.inqAuthrt === 'Y'; } else if (to.path.includes('/insert.page')) { // 등록 및 수정 권한 검증 return mbrAuth.includes(auth.authrtCd) && auth.regAuthrt === 'Y'; } else if (to.path.includes('/view.page')) { // 상세조회 권한 검증 return mbrAuth.includes(auth.authrtCd) && auth.inqAuthrt === 'Y'; } else if (to.path.includes('/main.page')) { // 메인 페이지 권한 검증 return mbrAuth.includes(auth.authrtCd) && auth.inqAuthrt === 'Y'; } else if (to.path.includes('/search.page')) { return mbrAuth.includes(auth.authrtCd) && auth.inqAuthrt === 'Y'; } else { return false; } }); }); // 권한이 있고 접근 가능한 경우 if (hasAcc) { if (to.path.includes('.page')) { let logicalPath = to.path; // context path 제거 if (contextPath !== '/' && logicalPath.startsWith(contextPath)) { logicalPath = logicalPath.substring(contextPath.length); } const lastSlashIndex = logicalPath.lastIndexOf('/'); // 마지막 '/' 인덱스 const path = logicalPath.substring(0, lastSlashIndex); // 마지막 '/' 이전 경로 store.commit('setPath', path); } // 접속 통계 if (to.path.includes('/main.page')) { await cntnStatsSave(null, mbrAuth); // 메인 페이지 접속 시 사용자 접속 통계 증가 } else { if (!to.meta.typeId.includes('BBS_MNG') || to.path.includes('/list.page')) { await cntnStatsSave(to.meta.typeId, mbrAuth); } } store.commit('setPageAuth', pageAuth); next(); // 권한이 없는 경우 이전 페이지 or / 이동 } else { alert('접근 권한이 없습니다.'); window.history.back(); // next(from.fullPath ? from.fullPath : '/'); } } else { // sessionStorage.setItem("redirect", to.fullPath); next({ path: filters.ctxPath("/login.page") }); } }); return AppRouter; }