
File name
Commit message
Commit date
05-22
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import { createWebHistory, createRouter } from "vue-router";
import { getGlobalStore } 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";
// NotFound
import NotFound from "./user/etc/NotFound.vue";
const beforeRoutes = [
/* 메인화면 */
{ path: "/", name: "main", korName: "홈", component: Main },
{ path: '/:pathMatch(.*)*', name: "PageNotFound", component: NotFound },
// 관리자
{
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";
// Context Path 정보 호출
async function getContextPath() {
try {
const store = getGlobalStore(); // 전역 스토어 가져오기
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 store = getGlobalStore(); // 전역 스토어 가져오기
const res = await findAll();
if (res.status == 200) {
const newRoutes = res.data.data.map(route => ({
path: route.userPagePath,
name: route.contsEngNm,
korName: route.contsKornNm,
component: () => import(`${route.compnPath}`),
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 store = getGlobalStore(); // 전역 스토어 가져오기
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 store = getGlobalStore(); // 전역 스토어 가져오기
const contextPath = store.state.contextPath; // Context Path 정보
const admPath = to.path.includes('/adm'); // 관리자 페이지 여부 (true: 관리자 페이지, false: 사용자 페이지)
if(to.name === 'PageNotFound') {
next();
return;
}
// 로그인 모드 확인
let loginMode = store.state.loginMode;
// 로그인 모드가 여전히 없으면 localStorage에서 다시 한번 확인
if (!loginMode || loginMode === 'undefined') {
// 스토어에 없으면 localStorage 확인
loginMode = localStorage.getItem('loginMode') || sessionStorage.getItem('loginMode');
}
if (!loginMode || loginMode === 'undefined') {
// 여전히 없으면 기본값 설정
loginMode = 'J';
}
if (store.state.loginMode !== loginMode) {
store.commit('setLoginMode', loginMode);
}
// 로그인 상태 확인 개선
let isLogin = false;
if (loginMode === 'J') {
// JWT 모드: authorization 토큰 확인
const token = store.state.authorization || localStorage.getItem('authorization');
isLogin = !!token;
} else if (loginMode === 'S') {
// 세션 모드: mbrId 또는 mbrNm 확인
const mbrId = store.state.mbrId || localStorage.getItem('mbrId') || sessionStorage.getItem('mbrId');
const mbrNm = store.state.mbrNm || localStorage.getItem('mbrNm') || sessionStorage.getItem('mbrNm');
isLogin = !!(mbrId || mbrNm);
}
// OAuth2 콜백 처리 - 로그인 페이지에서만 처리
if (to.path.includes('/login.page') && (to.query.oauth_success || to.query.error)) {
next();
return;
}
// 접근 제어 확인
const accesCheck = await accessUrl(to.path);
const roleCheck = isValidRole();
if (!accesCheck || !roleCheck) {
alert('접근이 불가합니다.\n관리자에게 문의하세요.');
next(filters.ctxPath('/'));
return;
}
// 경로에 따른 사용자 타입 설정
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.includes('/cmslogin.page') || to.path.startsWith(filters.ctxPath('/cmmn/')) || to.path.includes('/signUp.page') || 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 (to.path === filters.ctxPath('/') || path.includes('/main.page')) {
await cntnStatsSave(null, mbrAuth); // 메인 페이지 접속 시 사용자 접속 통계 증가
}
next();
} else if (isLogin) {
// 로그인 상태이고, 권한이 허용인 경우 검사
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();
}
} else {
// 관리자 로그인이 필요한 경우
if(admPath) {
sessionStorage.setItem("redirect", to.fullPath);
next({ path: filters.ctxPath("/cmslogin.page") });
} else {
// 일반 사용자 페이지에서 로그인이 필요한 경우
sessionStorage.setItem("redirect", to.fullPath);
next({ path: filters.ctxPath("/login.page") });
}
}
});
return AppRouter;
}