๐ก ๋ฌธ์ ์
์ ๋์๋ฒ ์ด ํ ์คํธ ์ค์ URL์ ํ๋ก์ ํธ ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ฉด ๊ถํ์ด ์๋๋ผ๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ ๋ฌธ์ ์ ์ด ๋ฐ๊ฒฌ๋์๋ค.
ํ๋ก์ ํธ์ ๊ณ ์ ๋ฒํธ๊ฐ 630 ์ด๋ผ๊ณ ํ๋ฉด URL์ ์ง์ make/630 ๋ฑ ํ๋ก์ ํธ ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ฉด ๋ด ํ๋ก์ ํธ๊ฐ ์๋์ฌ๋ ํธ์ง ๋ฐ ์ค์ฌ ์งํ์ด ๊ฐ๋ฅํ๋ค.
โก ์์ธ
ํ๋ก์ ํธ์ ๊ด๋ จํ์ฌ ์ด ํ๋ก์ ํธ๊ฐ ๋ด ํ๋ก์ ํธ์ธ์ง ํ์ธํด์ฃผ๋ ๊ฒ์ฌ ๋ก์ง์ด ์์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ URL๋ก ์ง์ ์ ๋ ฅํ๊ฒ ๋๋ค๋ฉด ๋๊ตฌ๋ ์ ๊ทผํ ์ ์๋ ๋ฌธ์ ์ ์ด ์๋ค.
โ๏ธ ํด๊ฒฐ
- vue routes ์์ ์ฒ๋ฆฌ
๋ผ์ฐํฐ ์ด๋ ์ ์ ๊ถํ์ ๊ฒ์ฌํ๋ ๋ก์ง์ ์ง์ ์ ๊ทผ์ ๋ง๋ ๋ฐฉ๋ฒ
- Nest ์์ Custom Guards ๋ฅผ ๋ง๋ค์ด์ ์ฒ๋ฆฌ
์์ฒญ์ด ์์ ๊ฒฝ์ฐ ๋ฐฑ์๋์์ ๊ถํ์ ์กฐํํ๋ค.
์ด 2๊ฐ์ง ์ค ํ๋๋ง ํด์ค๋ ๊ถํ์ด ์๋ ํ๋ก์ ํธ์ ์ ๊ทผ ํ๋ ๊ฒ์ ๋ง์ ์ ์๋ค.
Vue Router Guard
// 1. ๋จผ์ Vue Routes์ meta ์ต์
์ ํ์ฉํ๋ค.
// EX: routes -> index.ts
Vue.use(VueRouter);
const routes: Array<RouteConfig> = [
.
.
{
path: '/login',
name: 'login',
component: Login,
meta: { unauthorized: true },
},
.
.
.
{
path: '/project/sampling/:id',
name: 'surveySampling',
component: Sampling,
meta: { projectAccess: true },
},
{
path: '/project/make/:id',
name: 'surveyMake',
component: Make,
meta: { projectAccess: true },
},
.
.
meta ์์ฑ ๊ฐ์ด true ์ผ ๊ฒฝ์ฐ ๊ฒ์ฌ๋ฅผ ํ๊ฒ ๋ค ๋ผ๋ ์๋ฏธ
์์ ์์ฑ์ ๊ฐ์ง๊ณ rotuer.before ์์ ๊ฒ์ฌ๋ฅผ ์ํํ ์ ์๋ค.
// router.beforeEach() ์กฐ๊ฑด ๊ฒ์ฌ
router.beforeEach(async (to: Route, from, next) => {
try {
const { matched } = to;
let verifyFlag = true;
const isUnauthorized = matched.some((record) => record.meta.unauthorized);
const { meta } = matched.find((record) => record.meta) || {};
const { role }: any = meta || { role: '' };
if (!isUnauthorized) {
const { result } = await store.dispatch('verify');
if (!result) {
verifyFlag = false;
return next('/login');
}
}
if (verifyFlag === true && role === 'ADMIN') {
if (!store.getters.isAdmin) {
await app.$toast.error('๊ถํ์ด ์๋ ํ์ด์ง ์
๋๋ค.');
return next('/project/list');
}
}
// MARK: ์ถ๊ฐ๋ ํ๋ก์ ํธ ๊ถํ ๊ฒ์ฌ
const projectAccess = matched.some((record) => record.meta.projectAccess);
if (projectAccess) {
const { params } = to;
const { id } = params;
const { data } = await store.dispatch('projectAccess', id);
const { result } = data;
if (result) return next();
else {
await app.$toast.error('์๋ชป๋ ์ ๊ทผ์
๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.');
return next('/project/list');
}
}
return next();
} catch (e) {
console.error(e);
}
});
๋ผ์ฐํ ์ด ๋ ๋ meta ์์ฑ์ด ์๋์ง ํ์ธ์ ํ๊ณ ์์ผ๋ฉด ํด๋นํ๋ ๊ฐ์ด ์๋์ง ํ์ธํ๊ฒ ๋๋ค.
project API ์ ๊ฒฝ์ฐ meta ์์ฑ์ด projectAccess ๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ์ธ ๋์ด์๋ค.
๋ฐ๋ผ์ beforeEach ์์ ๊ฒ์ฌ๋ฅผ ํต๊ณผํด์ผ ๋ ๋๋ง ๋๋๋ก ํ๋ค.
๋ฐฑ์๋์์ ์ ์กฐ๊ฑด์ ๊ฒ์ฌํ๊ณ ๊ทธ์ ๋ง๋ ๋ฐํ๊ฐ์ ๋๊ฒจ์ค๋ค.
์ผ์นํ๋ค๋ฉด true๋ฅผ ๋ฐํํ๊ฒ ํ์๊ณ , ์ผ์นํ์ง ์๋๋ค๋ฉด false๋ฅผ ๋ฐํํ๋ค.
๋ฐฑ์๋๋ก ํต์ ์ ํ ๋ Axios Instance๋ฅผ ์ฌ์ฉํ์๊ธฐ ๋๋ฌธ์ ๋ฐฑ์๋์์ ๋๊ฒจ์ง ๊ฐ๋ค์ ์ ์ผ ๋จผ์ axios์์ ๋ฐ๊ฒ ๋์ด์๋ค.
Vue Axios Instance Error Handling
๋ฐฑ์๋์์ ์ ๋ฌ ๋ฐ์ ๊ฐ์ผ๋ก ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
// utils -> axios.ts (Custom Axios instance)
import axios from 'axios';
import store from '@/store/index';
import router from '@/router/index';
import Vue from 'vue';
const baseURL = '/api';
const instance = axios.create({
baseURL,
headers: {
'Content-Type': 'application/json',
},
timeout: 20000,
});
// REQUEST (์์ฒญ)
instance.interceptors.request.use((config) => {
if (store) {
const { token } = store.getters;
if (token) config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
});
// RESPONSE (์๋ต)
instance.interceptors.response.use((response) => {
return response;
},
(error) => {
const { response } = error;
const { data, status } = response;
const { message } = data;
if (status === 401) {
return router.replace({ path: '/' }).catch(() => ({}));
} else {
Vue.$toast.error(message);
console.log('debug-', data);
}
return response;
}
);
export const ins = instance;
๋ฐฑ์๋์์ ์๋ต๊ฐ์ด ์ ๋๋ก ์ ๋ฌ๋๋ค๋ฉด axios ์์ onFulfilled(response)์ ์ ๋ฌ๋๋ค.
๋ง์ฝ ์๋ฌ๊ฐ ๋ฐ์๋๋ค๋ฉด onRejected(error)์ ์ ๋ฌ์ด ๋๋๋ฐ ์ด๋ฅผ ๊ฐ์ง๊ณ ์ํ๋ ํํ๋ก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
๋ง๋ฌด๋ฆฌ
์ฌ์ค ์ด๊ธฐ์๋ ๋ผ์ฐํธ๋ฅผ ์ด์ฉํ์ง ์๊ณ , ๋ฐฑ์๋์์ ๊ฐ๋๋ฅผ ๋ง๋ค์ด ์ฒ๋ฆฌ๋ฅผ ํ ์๊ฐ์ด์๋ค.
ํ์ง๋ง... Nest์์ ๊ฐ๋๋ฅผ ๋ง๋ค์ด ๋ณธ ๊ฒฝํ์ด ์์ด์ ์ฐพ์์ ๋ง๋ค์ด ๋ณด๋๋ฐ ์๊ฐ์ด ์ค๋๊ฑธ๋ฆด ๊ฒ ๊ฐ์ ๊ธํ๋๋ก ํ๋ก ํธ์์ ๋ง๋ ๋ฐฉ๋ฒ์ ์ ํํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค Router Guard์ ์ญํ ์ ์๊ณ ์์์ง๋ง ์ด๋ฒ์ฒ๋ผ ์ ๋๋ก ๋ค๋ค ๋ณธ ์ ์ ์์๋ค.
์ด๋ฒ์ Router Guard์ axios๋ฅผ ์ง์ custom ํด๋ณด๋ฉด์ ์ด ๋์ ์ดํดํ๋๋ฐ ํฐ ๋์์ด ๋์๋ค.
์ผ๋จ ์ํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ์์ผ๋ Nest Guard๋ ๊ตฌํ์ด ๋๋๋๋ก ์ ๋ฆฌํด ๋ณด์.
'๊ฐ๋ฐ๋ ธํธ > Note' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ฌ์ด๋ ํ๋ก์ ํธ - ๋ทํฌ (Dotto) (0) | 2023.02.13 |
---|---|
[TIL] Vue์์์ ๋ฐฑ์๋ ํต์ (0) | 2022.11.14 |
[TIL] JavaScript Function (2022-08-10 ๋ด์ฉ ์ด์ ) (0) | 2022.09.08 |
[WEB] JSON (JavaScript Object Notation) (0) | 2021.06.07 |
[WEB] Ajax(Asynchronous Javascript And XML) (0) | 2021.06.07 |