Vue 3 ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ์ ์ํ ๋ผ์ฐํ ๊ฐ๋: ์ค์ ํจํด
Vue 3 ๋ผ์ฐํ ๊ฐ๋๋ฅผ ํตํ ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ์ ์ค์ ํจํด์ผ๋ก ์ค๋ช ํฉ๋๋ค: ๋ผ์ฐํธ meta ๊ท์น, ์์ ํ ๋ฆฌ๋ค์ด๋ ํธ, ์น์ ํ 401/403 ํด๋ฐฑ, ๋ฐ์ดํฐ ์ ์ถ ๋ฐฉ์ง ๋ฐฉ๋ฒ ํฌํจ.

๋ผ์ฐํธ ๊ฐ๋๊ฐ ์ค์ ๋ก ํด๊ฒฐํ๋ ๊ฒ(๊ทธ๋ฆฌ๊ณ ํด๊ฒฐํ์ง ๋ชปํ๋ ๊ฒ)\n\n๋ผ์ฐํธ ๊ฐ๋๋ ํ ๊ฐ์ง ์ผ์ ์ํฉ๋๋ค: ๋ค๋น๊ฒ์ด์
์ ์ ์ดํฉ๋๋ค. ๋๊ฐ ๊ฒฝ๋ก์ ์ง์
ํ ์ ์๋์ง, ์ง์
ํ ์ ์์ ๋ ์ด๋๋ก ๋ณด๋ผ์ง ๊ฒฐ์ ํฉ๋๋ค. ์ด๋ UX๋ฅผ ๊ฐ์ ํ์ง๋ง ๋ณด์๊ณผ๋ ๋ณ๊ฐ์
๋๋ค.\n\n๋ฉ๋ด ํญ๋ชฉ์ ์จ๊ธฐ๋ ๊ฒ์ ํํธ์ผ ๋ฟ์
๋๋ค. ์ฌ๋๋ค์ ์ฌ์ ํ URL์ ์
๋ ฅํ๊ฑฐ๋, ๋ฅ ๋งํฌ์์ ์๋ก๊ณ ์นจํ๊ฑฐ๋, ์ฆ๊ฒจ์ฐพ๊ธฐ๋ฅผ ์ด ์ ์์ต๋๋ค. ๋ง์ฝ ์ ์ผํ ๋ณดํธ๊ฐ "๋ฒํผ์ด ๋ณด์ด์ง ์๋๋ค"๋ผ๋ฉด, ๋ณดํธ๊ฐ ์๋ ๊ฒ์
๋๋ค.\n\n๊ฐ๋๋ ๊ด๋ฆฌ์ ์์ญ, ๋ด๋ถ ๋๊ตฌ, ์ญํ ๊ธฐ๋ฐ ๊ณ ๊ฐ ํฌํธ์ฒ๋ผ ๋ณด์ฌ์๋ ์ ๋๋ ํ์ด์ง๋ฅผ ์ฐจ๋จํ๋ฉด์ ์ฑ์ด ์ผ๊ด๋๊ฒ ๋์ํ๋๋ก ํ ๋ ๋น์ ๋ฐํฉ๋๋ค.\n\n๊ฐ๋๋ฅผ ํตํด ์ป๋ ์ด์ :\n\n- ํ์ด์ง๊ฐ ๋ ๋๋ง๋๊ธฐ ์ ์ ์ฐจ๋จ\n- ๋ก๊ทธ์ธ์ด๋ ์์ ํ ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ก ๋ฆฌ๋ค์ด๋ ํธ\n- ๊นจ์ง ๋ทฐ ๋์ ๋ช
ํํ 401/403 ํ๋ฉด ์ ๊ณต\n- ์ฐ๋ฐ์ ์ธ ๋ค๋น๊ฒ์ด์
๋ฃจํ ํํผ\n\n๊ฐ๋๋ง์ผ๋ก๋ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ ์ ์์ต๋๋ค. API๊ฐ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ผ์ฐ์ ๋ก ๋ฐํํ๋ฉด, ํ์ด์ง๊ฐ ์ฐจ๋จ๋๋๋ผ๋ ์ฌ์ฉ์๋ ๊ทธ ์๋ํฌ์ธํธ๋ฅผ ์ง์ ํธ์ถํ๊ฑฐ๋ ๊ฐ๋ฐ์ ๋๊ตฌ๋ก ์๋ต์ ํ์ธํ ์ ์์ต๋๋ค. ์ค์ ๊ถํ ๊ฒ์ฌ๋ ์๋ฒ์์๋ ์ด๋ค์ ธ์ผ ํฉ๋๋ค.\n\n์ข์ ๋ชฉํ๋ ์์ชฝ์ ๋ชจ๋ ์ปค๋ฒํ๋ ๊ฒ์
๋๋ค: ํ์ด์ง๋ฅผ ์ฐจ๋จํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฐจ๋จํ์ธ์. ์ง์ ๋ด๋น์๊ฐ ๊ด๋ฆฌ์ ์ ์ฉ ๊ฒฝ๋ก๋ฅผ ์ด๋ฉด ๊ฐ๋๋ ๋ค๋น๊ฒ์ด์
์ ์ค๋จํ๊ณ "Access denied"๋ฅผ ๋ณด์ฌ์ค์ผ ํฉ๋๋ค. ๋ณ๋๋ก ๋ฐฑ์๋๋ ๊ด๋ฆฌ์ ์ ์ฉ API ํธ์ถ์ ๊ฑฐ๋ถํด ์ ํ๋ ๋ฐ์ดํฐ๊ฐ ์ ๋ ๋ฐํ๋์ง ์๋๋ก ํด์ผ ํฉ๋๋ค.\n\n## ๊ฐ๋จํ ์ญํ ๋ฐ ๊ถํ ๋ชจ๋ธ ์ ํ\n\n์ญํ ๋ชฉ๋ก์ด ๊ธธ์ด์ง๋ฉด ์ ๊ทผ ์ ์ด๊ฐ ๋ณต์กํด์ง๋๋ค. ์ค์ ๋ก ์ฌ๋๋ค์ด ์ดํดํ๋ ์์ ์งํฉ์ผ๋ก ์์ํ๊ณ , ์ง์ง๋ก ํ์ํ ๋๋ง ์ธ๋ถ ๊ถํ์ ์ถ๊ฐํ์ธ์.\n\n์ค์ฉ์ ์ธ ๋ถ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:\n\n- ์ญํ (Roles)์ ์ฑ์์ ๋๊ตฐ์ง๋ฅผ ์ค๋ช
ํฉ๋๋ค.\n- ๊ถํ(Permissions)์ ๋ฌด์์ ํ ์ ์๋์ง๋ฅผ ์ค๋ช
ํฉ๋๋ค.\n\n๋๋ถ๋ถ์ ๋ด๋ถ ๋๊ตฌ์์๋ ์ธ ๊ฐ์ง ์ญํ ์ด๋ฉด ์ถฉ๋ถํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค:\n\n- admin: ์ฌ์ฉ์ ๋ฐ ์ค์ ๊ด๋ฆฌ, ๋ชจ๋ ๋ฐ์ดํฐ ํ์ธ\n- support: ๊ณ ๊ฐ ๊ธฐ๋ก๊ณผ ์๋ต ์ฒ๋ฆฌ, ์์คํ
์ค์ ์ ์๋\n- viewer: ์น์ธ๋ ํ๋ฉด์ ๋ํ ์ฝ๊ธฐ ์ ์ฉ ์ ๊ทผ\n\n์ญํ ์ด ์ด๋์ ์ค๋์ง ์ผ์ฐ ๊ฒฐ์ ํ์ธ์. ํ ํฐ ํด๋ ์(JWT)์ ๊ฐ๋์ ๋น ๋ฅด์ง๋ง ๊ฐฑ์ ๋ ๋๊น์ง ์ค๋๋ ์ํ๊ฐ ๋ ์ ์์ต๋๋ค. ์ฑ ์์ ์ ์ฌ์ฉ์ ํ๋กํ์ ๊ฐ์ ธ์ค๋ฉด ํญ์ ์ต์ ์ด์ง๋ง ๊ฐ๋๊ฐ ๊ทธ ์์ฒญ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.\n\n๋ํ ๋ผ์ฐํธ ์ ํ์ ๋ช
ํํ ๋ถ๋ฆฌํ์ธ์: ๊ณต๊ฐ ๋ผ์ฐํธ(๋ชจ๋ ์ ๊ทผ), ์ธ์ฆ๋ ๋ผ์ฐํธ(์ธ์
ํ์), ์ ํ๋ ๋ผ์ฐํธ(์ญํ ๋๋ ๊ถํ ํ์).\n\n## ๋ผ์ฐํธ meta๋ก ์ ๊ทผ ๊ท์น ์ ์\n\n์ ๊ทผ์ ํํํ๋ ๊ฐ์ฅ ๊น๋ํ ๋ฐฉ๋ฒ์ ๋ผ์ฐํธ ์์ฒด์ ์ ์ธํ๋ ๊ฒ์
๋๋ค. Vue Router๋ ๊ฐ ๋ผ์ฐํธ ๋ ์ฝ๋์ meta ๊ฐ์ฒด๋ฅผ ๋ถ์ผ ์ ์์ด ๊ฐ๋๊ฐ ๋์ค์ ์ฝ์ ์ ์์ต๋๋ค. ์ด๋ ๊ท์น์ ๋ณดํธํ ํ์ด์ง ๊ฐ๊น์ด์ ๋์ด ๊ด๋ฆฌํ๊ธฐ ์ฝ์ต๋๋ค.\n\n๋จ์ํ meta ํํ๋ฅผ ์ ํํ๊ณ ์ฑ ์ ์ฒด์์ ์ผ๊ด๋๊ฒ ์ฌ์ฉํ์ธ์.\n\njs\nconst routes = [\n {\n path: "/admin",\n component: () => import("@/pages/AdminLayout.vue"),\n meta: { requiresAuth: true, roles: ["admin"] },\n children: [\n {\n path: "users",\n component: () => import("@/pages/AdminUsers.vue"),\n // inherits requiresAuth + roles from parent\n },\n {\n path: "audit",\n component: () => import("@/pages/AdminAudit.vue"),\n meta: { permissions: ["audit:read"] },\n },\n ],\n },\n {\n path: "/tickets",\n component: () => import("@/pages/Tickets.vue"),\n meta: { requiresAuth: true, permissions: ["tickets:read"], readOnly: true },\n },\n]\n\n\n์ค์ฒฉ ๋ผ์ฐํธ์ ๊ฒฝ์ฐ ๊ท์น์ ์ด๋ป๊ฒ ๊ฒฐํฉํ ์ง ๊ฒฐ์ ํ์ธ์. ๋๋ถ๋ถ์ ์ฑ์์๋ ์์์ด ๋ถ๋ชจ ์๊ตฌ์ฌํญ์ ์์ํด์ผ ํฉ๋๋ค. ๊ฐ๋์์๋ ๋งค์น๋ ๋ชจ๋ ๋ผ์ฐํธ ๋ ์ฝ๋(๋จ์ํ to.meta๋ง์ด ์๋๋ผ)๋ฅผ ๊ฒ์ฌํด ๋ถ๋ชจ ๊ท์น์ด ๊ฑด๋๋ฐ์ด์ง์ง ์๋๋ก ํ์ธ์.\n\n๋์ค์ ์๊ฐ์ ์ ์ฝํด์ฃผ๋ ํ ๊ฐ์ง ์ธ๋ถ์ฌํญ: "์กฐํ ๊ฐ๋ฅ(can view)"๊ณผ "์์ ๊ฐ๋ฅ(can edit)"์ ๊ตฌ๋ถํ์ธ์. ์ด๋ค ๋ผ์ฐํธ๋ support์ admin์ด ๋ณผ ์ ์์ง๋ง, support๋ ์์ ์ ๋นํ์ฑํํด์ผ ํ ์ ์์ต๋๋ค. meta์ readOnly: true ํ๋๊ทธ๋ฅผ ๋๋ฉด UI ๋์(์ก์
๋นํ์ฑํ, ํ๊ดด์ ๋ฒํผ ์จ๊ธฐ๊ธฐ)์ ์ ์ดํ ์ ์๊ณ , ์ด๋ฅผ ๋ณด์์ผ๋ก ์คํดํ์ง ์๊ฒ ๋ฉ๋๋ค.\n\n## ๊ฐ๋๊ฐ ์ ๋ขฐ์ฑ ์๊ฒ ๋์ํ๋๋ก ์ธ์ฆ ์ํ ์ค๋น\n\n๊ฐ๋ ๋ฒ๊ทธ์ ๋๋ถ๋ถ์ ํ ๊ฐ์ง ๋ฌธ์ ์์ ์ต๋๋ค: ๊ฐ๋๊ฐ ์ฑ์ด ์ฌ์ฉ์๋ฅผ ์๊ธฐ ์ ์ ์คํ๋๋ ๊ฒฝ์ฐ์
๋๋ค.\n\n์ธ์ฆ์ ์์ ์ํ ๋จธ์ ์ฒ๋ผ ์ทจ๊ธํ๊ณ ๊ทธ๊ฒ์ ๋จ์ผ ์ ๋ขฐ ์์ค๋ก ๋ง๋์ธ์. ์ธ ๊ฐ์ง ๋ช
ํํ ์ํ๊ฐ ํ์ํฉ๋๋ค:\n\n- unknown: ์ฑ์ด ๋ง ์์ํ๊ณ ์ธ์
์ด ์์ง ํ์ธ๋์ง ์์\n- logged out: ์ธ์
ํ์ธ์ด ๋๋ฌ๊ณ ์ ํจํ ์ฌ์ฉ์๊ฐ ์์\n- logged in: ์ฌ์ฉ์ ๋ก๋ ์๋ฃ, ์ญํ /๊ถํ ์ด์ฉ ๊ฐ๋ฅ\n\n๊ท์น: ์ธ์ฆ์ด unknown์ผ ๋ ์ ๋ ์ญํ ์ ์ฝ์ง ๋ง์ธ์. ์ด๊ฒ์ด ๋ณดํธ๋ ํ๋ฉด์ ํ๋์๋ ๋๋ผ์ด ๋ก๊ทธ์ธ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ง๋๋ ์์ธ์
๋๋ค.\n\n### ์ธ์
๊ฐฑ์ ๋ฐฉ์ ๊ฒฐ์ \n\nํ๋์ ๊ฐฑ์ ์ ๋ต์ ์ ํ๊ณ ์์ธก ๊ฐ๋ฅํ๊ฒ ์ ์งํ์ธ์(์: ํ ํฐ ์ฝ๊ธฐ, who am I ์๋ํฌ์ธํธ ํธ์ถ, ์ฌ์ฉ์ ์ค์ ).\n\n์์ ์ ์ธ ํจํด ์์:\n\n- ์ฑ ๋ก๋ ์ ์ธ์ฆ์ unknown์ผ๋ก ์ค์ ํ๊ณ ๋จ์ผ ๊ฐฑ์ ์์ฒญ์ ์์\n- ๊ฐฑ์ ์ด ๋๋๊ฑฐ๋ ํ์์์๋ ๋๊น์ง ๊ฐ๋๋ ํด์ ํ์ง ์์\n- ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฉํ ๋์ ๋ฉ๋ชจ๋ฆฌ์ ์บ์\n- ์คํจ ์ ์ธ์ฆ์ logged out์ผ๋ก ์ค์ \n- ๊ฐ๋๊ฐ ๋๊ธฐํ ์ ์๋ ready ํ๋ผ๋ฏธ์ค(๋๋ ์ ์ฌ)๋ฅผ ๋
ธ์ถ\n\n์ด๊ฒ ๋ง๋ จ๋๋ฉด ๊ฐ๋ ๋ก์ง์ ๋จ์ํด์ง๋๋ค: auth๊ฐ ์ค๋น๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ ๊ทผ์ ๊ฒฐ์ ํ์ธ์.\n\n## ๋จ๊ณ๋ณ: ๋ผ์ฐํธ ์์ค ๊ถํ ๊ตฌํ\n\n๊น๋ํ ์ ๊ทผ๋ฒ์ ๋๋ถ๋ถ์ ๊ท์น์ ํ๋์ ์ ์ญ ๊ฐ๋์ ๋๊ณ , ๋ผ์ฐํธ๋ณ๋ก ์ง์ง๋ก ํน๋ณํ ๋ก์ง์ด ํ์ํ ๋๋ง beforeEnter๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.\n\n### 1) ์ ์ญ beforeEach ๊ฐ๋ ์ถ๊ฐ\n\njs\n// router/index.js\nrouter.beforeEach(async (to) => {\n const auth = useAuthStore()\n\n // Step 2: wait for auth initialization when needed\n if (!auth.ready) await auth.init()\n\n // Step 3: check authentication, then roles/permissions\n if (to.meta.requiresAuth && !auth.isAuthenticated) {\n return { name: 'login', query: { redirect: to.fullPath } }\n }\n\n const roles = to.meta.roles\n if (roles && roles.length > 0 && !roles.includes(auth.userRole)) {\n return { name: 'forbidden' } // 403\n }\n\n // Step 4: allow navigation\n return true\n})\n\n\n์ด ํจํด์ ์ปดํฌ๋ํธ ์ ์ญ์ ์ฒดํฌ๋ฅผ ํฉ์ด๋์ง ์๊ณ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.\n\n### beforeEnter๊ฐ ๋ ์ ํฉํ ๊ฒฝ์ฐ\n\nbeforeEnter๋ ๊ท์น์ด ์ง์ง๋ก ๋ผ์ฐํธ๋ณ์ด๊ณ to.params.id์ ์์กดํ ๋ ์ฌ์ฉํ์ธ์(์: "ํฐ์ผ ์์ ์๋ง ์ด ์ ์๋ค"). ์งง๊ฒ ์ ์งํ๊ณ ๋์ผํ ์ธ์ฆ ์คํ ์ด๋ฅผ ์ฌ์ฌ์ฉํด ๋์์ ์ผ๊ด๋๊ฒ ๋ง๋์ธ์.\n\n## ํ์ ๋ง๋ค์ง ์๋ ์์ ํ ๋ฆฌ๋ค์ด๋ ํธ\n\n๋ฆฌ๋ค์ด๋ ํธ๋ ์ ๋ขฐํ๋ฉด ์ ๊ทผ ์ ์ด๋ฅผ ์กฐ์ฉํ ๋ฌด๋ ฅํํ ์ ์์ต๋๋ค.\n\n์ผ๋ฐ ํจํด์: ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์ ์ํ๋ฉด ๋ก๊ทธ์ธ์ผ๋ก ๋ณด๋ด๊ณ returnTo ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์ ์๋ ๊ฒฝ๋ก๋ฅผ ๋ฃ์ต๋๋ค. ๋ก๊ทธ์ธ ํ ์ด๋ฅผ ์ฝ์ด ๋๋์๊ฐ๊ฒ ํ์ฃ . ์ํ์ ์คํ ๋ฆฌ๋ค์ด๋ ํธ(์๋ํ์ง ์์ ์ธ๋ถ๋ก ๋ณด๋ด๊ธฐ)์ ๋ฃจํ์
๋๋ค.\n\nํ๋์ ๋จ์ํ๊ฒ ์ ์งํ์ธ์:\n\n- ๋ก๊ทธ์์ ์ฌ์ฉ์๋ ํ์ฌ ๊ฒฝ๋ก๋ฅผ returnTo๋ก ์ค์ ํด Login์ผ๋ก ์ด๋\n- ๋ก๊ทธ์ธํ์ง๋ง ๊ถํ์ด ์๋ ์ฌ์ฉ์๋ ์ ์ฉ Forbidden ํ์ด์ง๋ก ๋ณด๋(๋ก๊ทธ์ธ ํ์ด์ง ์๋)\n- ํ์ฉ๋ ๋ด๋ถ returnTo ๊ฐ๋ง ํ์ฉ\n- ๊ฐ์ ๊ณณ์ผ๋ก ๊ณ์ ๋ฆฌ๋ค์ด๋ ํธํ๋ ๋ฃจํ ์ฒดํฌ ์ถ๊ฐ\n\njs\nconst allowedReturnTo = (to) => {\n if (!to || typeof to !== 'string') return null\n if (!to.startsWith('/')) return null\n // optional: only allow known prefixes\n if (!['/app', '/admin', '/tickets'].some(p => to.startsWith(p))) return null\n return to\n}\n\nrouter.beforeEach((to) => {\n if (!auth.isReady) return false\n\n if (!auth.isLoggedIn && to.name !== 'Login') {\n return { name: 'Login', query: { returnTo: to.fullPath } }\n }\n\n if (auth.isLoggedIn && !canAccess(to, auth.user) && to.name !== 'Forbidden') {\n return { name: 'Forbidden' }\n }\n})\n\n\n## ๋ค๋น๊ฒ์ด์
์ค ์ ํ๋ ๋ฐ์ดํฐ ์ ์ถ ๋ฐฉ์ง\n\n๊ฐ์ฅ ์ฌ์ด ์ ์ถ์ ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋ ๊ถํ์ธ์ง ์๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ๊ฒ์
๋๋ค.\n\nVue์์๋ ํ์ด์ง๊ฐ setup()์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋ผ์ฐํฐ ๊ฐ๋๊ฐ ๊ทธ๋ณด๋ค ๋ฆ๊ฒ ์คํ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ฃผ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋ฆฌ๋ค์ด๋ ํธ๋๋๋ผ๋ ์๋ต์ด ๊ณต์ ์คํ ์ด์ ๋จ๊ฑฐ๋ ํ๋ฉด์ ์ ๊น ๋ณด์ผ ์ ์์ต๋๋ค.\n\n์์ ํ ๊ท์น์: ๋จผ์ ๊ถํ์ ํ์ธํ๊ณ ๊ทธ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ์ธ์.\n\njs\n// router guard: authorize before entering the route\nrouter.beforeEach(async (to) => {\n await auth.ready() // ensure roles are known\n const required = to.meta.requiredRole\n if (required && !auth.hasRole(required)) {\n return { name: 'forbidden' }\n }\n})\n\n\n๋ํ ๋ค๋น๊ฒ์ด์
์ด ๋น ๋ฅด๊ฒ ๋ฐ๋ ๋ ๋ค์ด์ค๋ ๋ฆ์ ์์ฒญ์ ์ฃผ์ํ์ธ์. ์์ฒญ์ AbortController๋ก ์ทจ์ํ๊ฑฐ๋ ์์ฒญ ์์ด๋๋ฅผ ํ์ธํด ๋ฆ์ ์๋ต์ ๋ฌด์ํ์ธ์.\n\n์บ์ฑ๋ ํํ ํจ์ ์
๋๋ค. "๋ง์ง๋ง์ผ๋ก ๋ก๋ํ ๊ณ ๊ฐ ๋ ์ฝ๋"๋ฅผ ์ ์ญ์ ์ ์ฅํ๋ฉด ๊ด๋ฆฌ์ ์ ์ฉ ์๋ต์ด ์ดํ์ ์ผ๋ฐ ์ฌ์ฉ์์๊ฒ ํ์๋ ์ ์์ต๋๋ค. ์บ์๋ ์ฌ์ฉ์ id์ ์ญํ ๋ก ํค๋ฅผ ๋ง๋ค๊ฑฐ๋ ๋ก๊ทธ์์ ์(๋๋ ์ญํ ๋ณ๊ฒฝ ์) ๋ฏผ๊ฐํ ๋ชจ๋์ ์ ๋ฆฌํ์ธ์.\n\n๋ช ๊ฐ์ง ์ต๊ด์ผ๋ก ๋๋ถ๋ถ ์ ์ถ์ ์๋ฐฉํ ์ ์์ต๋๋ค:\n\n- ๊ถํ์ด ํ์ธ๋๊ธฐ ์ ๊น์ง ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ ๊ฐ์ ธ์ค์ง ๋ง์ธ์.\n- ์บ์๋ฅผ ์ฌ์ฉ์์ ์ญํ ๋ก ๊ตฌ๋ถํ๊ฑฐ๋ ํ์ด์ง ๋ก์ปฌ๋ก ์ ์งํ์ธ์.\n- ๋ผ์ฐํธ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์งํ ์ค์ธ ์์ฒญ์ ์ทจ์ํ๊ฑฐ๋ ๋ฌด์ํ์ธ์.\n\n## ์น์ ํ ํด๋ฐฑ: 401, 403, ๊ทธ๋ฆฌ๊ณ ์ฐพ์ ์ ์์\n\n"๊ฑฐ๋ถ" ๊ฒฝ๋ก๋ ํ์ฉ ๊ฒฝ๋ก๋งํผ ์ค์ํฉ๋๋ค. ์ข์ ํด๋ฐฑ ํ์ด์ง๋ ์ฌ์ฉ์๋ฅผ ๋ฐฉํฅ๊ฐ ์๊ฒ ์๋ดํ๊ณ ์ง์ ์์ฒญ์ ์ค์ฌ์ค๋๋ค.\n\n### 401: ๋ก๊ทธ์ธ ํ์(๋น์ธ์ฆ)\n\n์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ์ง ์์์ ๋ 401์ ์ฌ์ฉํ์ธ์. ๋ฉ์์ง๋ ๋จ์ํ๊ฒ ์ ์งํ์ธ์: ๊ณ์ํ๋ ค๋ฉด ๋ก๊ทธ์ธํด์ผ ํฉ๋๋ค. ์๋ ํ์ด์ง๋ก ๋์๊ฐ๋ ๊ธฐ๋ฅ์ ์ง์ํ๋ฉด ๋ฆฌํด ๊ฒฝ๋ก๋ฅผ ๊ฒ์ฆํด ์ฑ ์ธ๋ถ๋ก ๋๊ฐ์ง ์๋๋ก ํ์ธ์.\n\n### 403: ์ ๊ทผ ๊ฑฐ๋ถ(์ธ์ฆ๋จ, ๊ทธ๋ฌ๋ ํ์ฉ๋์ง ์์)\n\n์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ์ง๋ง ๊ถํ์ด ์์ ๋ 403์ ์ฌ์ฉํ์ธ์. ์ค๋ฆฝ์ ์ด๊ณ ๋ฏผ๊ฐํ ์ธ๋ถ์ฌํญ์ ์์ํ์ง ์๋ ๋ฌธ๊ตฌ๊ฐ ์ข์ต๋๋ค.\n\n๊ฒฌ๊ณ ํ 403 ํ์ด์ง๋ ๋ณดํต ๋ช
ํํ ์ ๋ชฉ(โAccess deniedโ), ํ ๋ฌธ์ฅ์ ์ค๋ช
, ๊ทธ๋ฆฌ๊ณ ์์ ํ ๋ค์ ๋จ๊ณ(๋์๋ณด๋๋ก ๋์๊ฐ๊ธฐ, ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์, ๊ณ์ ์ ํ)๊ฐ ์์ต๋๋ค.\n\n### 404: ์ฐพ์ ์ ์์\n\n404๋ 401/403๊ณผ ๋ณ๋๋ก ์ฒ๋ฆฌํ์ธ์. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฌ์ฉ์๋ ๋จ์ํ ํ์ด์ง๊ฐ ์๋๋ฐ ๊ถํ์ด ์๋ค๊ณ ์คํดํ ์ ์์ต๋๋ค.\n\n## ์ ๊ทผ ์ ์ด๋ฅผ ๋ง์น๋ ์ผ๋ฐ์ ์ธ ์ค์\n\n๋๋ถ๋ถ์ ์ ๊ทผ ์ ์ด ๋ฒ๊ทธ๋ ๊ฐ๋จํ ๋
ผ๋ฆฌ ์ค์๋ก ๋ํ๋ฉ๋๋ค: ๋ฆฌ๋ค์ด๋ ํธ ๋ฃจํ, ์๋ชป๋ ํ์ด์ง ํ๋์, ์ฌ์ฉ์๊ฐ ๋ฉ์ถฐ๋ฒ๋ฆฌ๋ ํ์ ๋ฑ.\n\n์ฃผ๋ ์์ธ:\n\n- ์จ๊ธด UI๋ฅผ "๋ณด์"์ผ๋ก ๊ฐ์ฃผ (ํญ์ ๋ผ์ฐํฐ์ API์์ ์ญํ ์ ๊ฐ์ ์ ์ฉ)\n- ๋ก๊ทธ์์/๋ก๊ทธ์ธ ํ ์ค๋๋ ์ํ์์ ์ญํ ์ ์ฝ์\n- ๊ถํ ์๋ ์ฌ์ฉ์๋ฅผ ๋ค๋ฅธ ๋ณดํธ๋ ๋ผ์ฐํธ๋ก ๋ฆฌ๋ค์ด๋ ํธ(์ฆ์ ๋ฃจํ ๋ฐ์)\n- ์๋ก๊ณ ์นจ ์ "์ธ์ฆ ๋ก๋ฉ ์ค" ์๊ฐ์ ๋ฌด์ํจ\n- 401๊ณผ 403์ ํผ๋ํด ์ฌ์ฉ์ ํผ๋์ ์ด๋ํจ\n\nํ์ค์ ์ธ ์: ์ง์ ๋ด๋น์๊ฐ ๋ก๊ทธ์์ํ๊ณ ๊ฐ์ ์ปดํจํฐ์์ ๊ด๋ฆฌ์๊ฐ ๋ก๊ทธ์ธํ ๋, ๊ฐ๋๊ฐ ์ ์ธ์
์ด ํ์ธ๋๊ธฐ ์ ์ ์บ์๋ ์ญํ ์ ์ฝ์ผ๋ฉด ๊ด๋ฆฌ์๋ฅผ ์๋ชป ์ฐจ๋จํ๊ฑฐ๋, ๋ ์ํํ๊ฒ๋ ์ ๊น ํ์ฉํด ๋ฒ๋ฆด ์ ์์ต๋๋ค.\n\n## ๋ฐฐํฌ ์ ๋น ๋ฅธ ์ฒดํฌ๋ฆฌ์คํธ\n\n๋๋ฆฐ ๋คํธ์ํฌ, ๋ง๋ฃ๋ ์ธ์
, ๋ถ๋งํฌ๋ URL ๊ฐ์ ์ ๊ทผ ์ ์ด๊ฐ ๋ณดํต ๊นจ์ง๋ ์๊ฐ์ ์ง์คํด ์งง๊ฒ ์ ๊ฒํ์ธ์.\n\n- ๋ชจ๋ ๋ณดํธ๋ ๋ผ์ฐํธ์ ๋ช
์์ meta ์๊ตฌ์ฌํญ ์กด์ฌ\n- ๊ฐ๋๋ ์ธ์ฆ ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํด ๋ณดํธ๋ UI๊ฐ ๊น๋นก์ด์ง ์์\n- ๊ถํ ์๋ ์ฌ์ฉ์๋ ๋ช
ํํ 403 ํ์ด์ง๋ก ์ด๋(ํผ๋์ค๋ฌ์ด ํ์ผ๋ก์ ํ๊น ์๋)\n- ๋ชจ๋ "๋์๊ฐ๊ธฐ" ๋ฆฌ๋ค์ด๋ ํธ๋ ๊ฒ์ฆ๋์ด ๋ฃจํ๋ฅผ ๋ง๋ค์ง ์์\n- ๋ฏผ๊ฐํ API ํธ์ถ์ ๊ถํ ํ์ธ ํ์๋ง ์คํ๋จ\n\n๊ทธ๋ฐ ๋ค์ ํ ์๋๋ฆฌ์ค๋ฅผ ๋๊น์ง ํ
์คํธํ์ธ์: ๋ก๊ทธ์์ ์ํ์์ ๋ณดํธ๋ URL์ ์ ํญ์ผ๋ก ์ด๊ณ , ๊ธฐ๋ณธ ์ฌ์ฉ์๋ก ๋ก๊ทธ์ธํ ๋ค ์๋๋ ํ์ด์ง๋ก ๊ฐ์ผ ํ๋์ง(ํ์ฉ๋๋ค๋ฉด) ๋๋ ๊น๋ํ 403๊ณผ ๋ค์ ๋จ๊ณ๋ฅผ ํ์ธํ์ธ์.\n\n## ์์: ์์ ์น ์ฑ์์ ์ง์๊ณผ ๊ด๋ฆฌ์ ์ ๊ทผ\n\nํฌํ๋ฐ์คํฌ ์ฑ์ ๊ฐ์ ํด ๋ณด์ธ์. ๋ ๊ฐ์ง ์ญํ ์ด ์์ต๋๋ค: support์ admin. Support๋ ํฐ์ผ์ ์ฝ๊ณ ์๋ตํ ์ ์์ต๋๋ค. Admin์ ๊ทธ ์ธ์๋ ๋น๋ง๊ณผ ํ์ฌ ์ค์ ์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.\n\n- /tickets/:id๋ support์ admin์ ํ์ฉ\n- /settings/billing์ admin๋ง ํ์ฉ\n\nํํ ์ํฉ: support ๋ด๋น์๊ฐ ์ค๋๋ ์ฆ๊ฒจ์ฐพ๊ธฐ์์ /settings/billing๋ก ๋ฅ ๋งํฌ๋ฅผ ์ฝ๋๋ค. ๊ฐ๋๋ ํ์ด์ง๊ฐ ๋ก๋๋๊ธฐ ์ ์ route meta๋ฅผ ํ์ธํด ๋ค๋น๊ฒ์ด์
์ ์ฐจ๋จํด์ผ ํฉ๋๋ค. ์ฌ์ฉ์๋ ๋ก๊ทธ์ธ์ ํ์ง๋ง ์ญํ ์ด ๋ถ์กฑํ๋ฏ๋ก ์์ ํ ํด๋ฐฑ(403)์ผ๋ก ๊ฐ์ผ ํฉ๋๋ค.\n\n๋ ๊ฐ์ง ๋ฉ์์ง๊ฐ ์ค์ํฉ๋๋ค:\n\n- ๋ก๊ทธ์ธ ํ์(401): โ๊ณ์ํ๋ ค๋ฉด ๋ก๊ทธ์ธํ์ธ์.โ\n- ์ ๊ทผ ๊ฑฐ๋ถ(403): โ์ฒญ๊ตฌ ์ค์ ์ ์ ๊ทผํ ์ ์์ต๋๋ค.โ\n\n์ ๋ ๋ฐ์ํ๋ฉด ์ ๋๋ ๊ฒ: billing ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๊ฑฐ๋ billing ๋ฐ์ดํฐ๋ฅผ ์ ๊น์ด๋ผ๋ ๊ฐ์ ธ์ค๋ ๊ฒ.\n\n์ธ์
์ค ์ญํ ๋ณ๊ฒฝ๋ ์ฃ์ง ์ผ์ด์ค์
๋๋ค. ๋๊ตฐ๊ฐ ์น๊ฒฉ๋๊ฑฐ๋ ๊ฐ๋ฑ๋๋ฉด ๋ฉ๋ด๋ง ๋ฏฟ์ง ๋ง์ธ์. ๋ค๋น๊ฒ์ด์
์ ์ญํ ์ ์ฌํ์ธํ๊ณ ํ์ฑ ํ์ด์ง๊ฐ ๋ ์ด์ ํ์ฉ๋์ง ์์ผ๋ฉด ์๋ก๊ณ ์นจํ๊ฑฐ๋ ๋ฆฌ๋ค์ด๋ ํธํ์ธ์.\n\n## ๋ค์ ๋จ๊ณ: ์ ๊ทผ ๊ท์น์ ์ ์ง ๊ฐ๋ฅํ๊ฒ ์ ์ง\n\n๊ฐ๋๊ฐ ๋์ํ๋ฉด ๋ ํฐ ์ํ์ ๊ท์น์ ๋ถ์ผ์น์
๋๋ค: ์ ๋ผ์ฐํธ๊ฐ meta ์์ด ๋ฐฐํฌ๋๊ฑฐ๋ ์ญํ ์ด ์ด๋ฆ์ด ๋ฐ๋๋ ๋ฑ ๊ท์น์ด ์ผ๊ด์ฑ์ ์์ ์ ์์ต๋๋ค.\n\n๋ผ์ฐํธ๋ฅผ ์ถ๊ฐํ ๋๋ง๋ค ์คํํ ์ ์๋ ์์ ํ
์คํธ ํ๋์ผ๋ก ๊ท์น์ ๊ด๋ฆฌํ์ธ์:\n\n- ๊ฒ์คํธ๋ก์ ๋ณดํธ๋ ๋ผ์ฐํธ๋ฅผ ์ด์ด ๋ถ๋ถ ์ฝํ
์ธ ๊ฐ ๋ณด์ด์ง ์๊ณ ๋ก๊ทธ์ธ์ผ๋ก ๊ฐ๋์ง ํ์ธ\n- ์ผ๋ฐ ์ฌ์ฉ์๋ก ์ ๊ทผ ๋ถ๊ฐํ ํ์ด์ง๋ฅผ ์ด์ด ๋ช
ํํ 403์ด ๋จ๋์ง ํ์ธ\n- ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ์ฃผ์์ฐฝ์์ ๋ฅ ๋งํฌ๋ฅผ ์๋\n- ๊ฐ ์ญํ ๋ณ๋ก ๋ณดํธ๋ ๋ผ์ฐํธ์์ ์๋ก๊ณ ์นจํด ๊ฒฐ๊ณผ๊ฐ ์์ ์ ์ธ์ง ํ์ธ\n\n์ถ๊ฐ ์์ ๋ง์ผ๋ก ๊ฐ๋ฐ ์ ์ฉ ๋ทฐ๋ ์ฝ์ ์ถ๋ ฅ์ ์ถ๊ฐํด ๋ผ์ฐํธ์ ๊ทธ meta ์๊ตฌ์ฌํญ์ ๋์ดํ๋ฉด ๋๋ฝ๋ ๊ท์น์ด ์ฆ์ ๋๋ฌ๋ฉ๋๋ค.\n\nAppMaster (appmaster.io)๋ก ๋ด๋ถ ๋๊ตฌ๋ ํฌํธ์ ๋ง๋ ๋ค๋ฉด ๋์ผํ ์ ๊ทผ๋ฒ์ ์ ์ฉํ์ธ์: Vue3 UI์์๋ ๋ค๋น๊ฒ์ด์
์ ๊ฐ๋๋ฅผ ์ง์ค์ํค๊ณ , ๊ถํ๊ณผ ๋ฐ์ดํฐ๋ ๋ฐฑ์๋ ๋ก์ง์์ ๊ฐ์ ํ์ธ์.\n\nํ ๊ฐ์ง ๊ฐ์ ์ ์ ๊ณจ๋ผ ๋๊น์ง ๊ตฌํํ์ธ์: ๋ฐ์ดํฐ ํ์นญ ๊ฒ์ดํ
๊ฐํ, 403 ํ์ด์ง ๊ฐ์ , ๋ฆฌ๋ค์ด๋ ํธ ์ฒ๋ฆฌ ์ ๊ธ ๋ฑ. ์์ ์์ ์ด ์ค์ ์ ๊ทผ ๋ฒ๊ทธ ๋๋ถ๋ถ์ ๋ง์ต๋๋ค.
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
๋ผ์ฐํธ ๊ฐ๋๋ ๋ค๋น๊ฒ์ด์ ์ ์ ์ดํฉ๋๋ค. ํ์ด์ง ์ง์ ์ ๋ง๊ณ ์ ์ ํ ๋ฆฌ๋ค์ด๋ ํธํ๊ฑฐ๋ ๊น๋ํ 401/403 ์ํ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ฐ ๋์์ ์ฃผ์ง๋ง, API๋ฅผ ์ง์ ํธ์ถํ๋ ๊ฒ์ ๋ง์ง๋ ๋ชปํฉ๋๋ค. ์ ํ๋ ๋ฐ์ดํฐ๊ฐ ๋ธ๋ผ์ฐ์ ๋ก ๋ฐํ๋์ง ์๋๋ก ์๋ฒ์์๋ ๋์ผํ ๊ถํ ๊ฒ์ฌ๋ฅผ ํญ์ ์ ์ฉํ์ธ์.
UI๋ฅผ ์จ๊ธฐ๋ ๊ฒ์ ์ฌ์ฉ์๊ฐ ๋ณด๋ ๊ฒ๋ง ๋ฐ๊ฟ ๋ฟ, ์์ฒญํ ์ ์๋ ๊ฒ์ ๋ง์ง๋ ์์ต๋๋ค. ์ฌ์ฉ์๋ URL์ ์ง์ ์ ๋ ฅํ๊ฑฐ๋ ์ฆ๊ฒจ์ฐพ๊ธฐ, ๋ฅ ๋งํฌ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. ํ์ด์ง ์ฐจ๋จ์ ๋ผ์ฐํฐ์์ ํ๊ณ , ๋ฐ์ดํฐ ์ฐจ๋จ์ ์๋ฒ์์ ํ์ธ์.
์ฌ๋๋ค์ด ์ดํดํ ์ ์๋ ์์ ์งํฉ์ผ๋ก ์์ํ๊ณ , ์ค์ ๋ก ๋ถํธํจ์ ๋๋ ๋ ์ธ๋ถ ๊ถํ์ ์ถ๊ฐํ์ธ์. ์ผ๋ฐ์ ์ธ ๊ธฐ๋ณธ ๊ตฌ์ฑ์ admin, support, viewer์ด๋ฉฐ, ํน์ ํ๋์๋ tickets:read๋ audit:read ๊ฐ์ ๊ถํ์ ์ถ๊ฐํฉ๋๋ค. โ๋๊ตฌ์ธ์งโ(role)์ โ๋ฌด์์ ํ ์ ์๋์งโ(permission)๋ฅผ ๋ถ๋ฆฌํ์ธ์.
meta์ ์ ๊ทผ ๊ท์น์ ๊ธฐ๋กํ์ธ์. ๋ผ์ฐํธ ๋ ์ฝ๋์ requiresAuth, roles, permissions ๊ฐ์ ๊ฐ์ ๋๋ฉด ์ ์ญ ๊ฐ๋๊ฐ ์์ธก ๊ฐ๋ฅํ๊ฒ ๋์ํฉ๋๋ค. ์ค์ฒฉ ๋ผ์ฐํธ์ ๊ฒฝ์ฐ ๋ถ๋ชจ ์๊ตฌ์ฌํญ์ด ๋๋ฝ๋์ง ์๋๋ก ๋ชจ๋ ๋งค์น๋ ๋ ์ฝ๋๋ฅผ ๊ฒ์ฌํ์ธ์.
๋ผ์ฐํธ์ to.matched๋ฅผ ์ฝ์ด ๋ชจ๋ ๋งค์น๋ ๋ ์ฝ๋์ ์๊ตฌ์ฌํญ์ ํฉ์น์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ์์ ๋ผ์ฐํธ๊ฐ ๋ถ๋ชจ์ requiresAuth๋ roles๋ฅผ ์ฐํํ์ง ๋ชปํฉ๋๋ค. ๋ณดํต์ ๋ถ๋ชจ ์๊ตฌ์ฌํญ์ด ์์์๊ฒ ์ ์ฉ๋๋ค๊ณ ์ ํ๋ฉด ๋ฉ๋๋ค.
๊ฐ๋๊ฐ ์ฑ์ด ์ฌ์ฉ์๋ฅผ ๋ชจ๋ฅผ ๋ ์คํ๋๋ฉด ํ๋์๋ ๋ฌดํ ๋ฆฌ๋ค์ด๋ ํธ๊ฐ ์๊น๋๋ค. ์ธ์ฆ ์ํ๋ฅผ unknown, logged out, logged in์ ์ธ ๊ฐ์ง๋ก ๋ค๋ฃจ๊ณ , unknown์ผ ๋๋ ์ญํ ์ ์ ๋ ํ๋จํ์ง ๋ง์ธ์. ๊ฐ๋๋ ์ด๊ธฐํ(์: who am I)๊ฐ ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
์ผ๊ด๋ ๊ท์น(์: โ๋ก๊ทธ์ธ ํ์โ, โ๊ถํ ํ์โ)์ ์ ์ญ beforeEach์์ ์ฒ๋ฆฌํ์ธ์. beforeEnter๋ to.params.id์ฒ๋ผ ๊ฒฝ๋ก๋ณ๋ก ์ ๋ง ํน๋ณํ ๊ฒ์ฌ(์: ํฐ์ผ ์์ ์ ํ์ธ)๊ฐ ํ์ํ ๋๋ง ์ฐ์ธ์. ๋ ๊ฒฝ์ฐ ๋ชจ๋ ๋์ผํ ์ธ์ฆ ์์ค๋ฅผ ์ฌ์ฉํ๋๋ก ํ์ธ์.
returnTo๋ ์ ๋ขฐํ ์ ์๋ ์
๋ ฅ์ผ๋ก ์ทจ๊ธํ์ธ์. ๋ด๋ถ ๊ฒฝ๋ก๋ง ํ์ฉํ๊ณ (์: /๋ก ์์ํ๊ณ ํ์ฉ๋ ์ ๋์ฌ์ ๋งค์น๋๋ ๊ฐ), ๋์ผํ ์ฐจ๋จ๋ ๊ฒฝ๋ก๋ก ๋ค์ ๋ฆฌ๋ค์ด๋ ํธํ์ง ์๋๋ก ๋ฃจํ ์ฒดํฌ๋ฅผ ์ถ๊ฐํ์ธ์. ๋ก๊ทธ์์๋ ์ฌ์ฉ์๋ ๋ก๊ทธ์ธ์ผ๋ก, ๋ก๊ทธ์ธ์ ํ์ง๋ง ๊ถํ์ด ์๋ ์ฌ์ฉ์๋ ์ ์ฉ 403 ํ์ด์ง๋ก ๋ณด๋ด์ธ์.
์ธ์ฆ์ด ํ์ธ๋๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉด ์ ์ถ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ํ์ด์ง๊ฐ setup()์์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ๊ฐ๋๊ฐ ๊ทธ ์งํ ๋ฆฌ๋ค์ด๋ ํธํ๋ฉด ์๋ต์ด ์คํ ์ด์ ๋จ๊ฑฐ๋ ์ ๊น ํ๋ฉด์ ๋ณด์ผ ์ ์์ต๋๋ค. ๋ฏผ๊ฐํ ์์ฒญ์ ๊ถํ ํ์ธ ๋ค์ ์ํํ๊ณ , ๋ค๋น๊ฒ์ด์
์ด ๋ฐ๋ ๋๋ ์์ฒญ์ ์ทจ์ํ๊ฑฐ๋ ๋ฆ์ ์๋ต์ ๋ฌด์ํ์ธ์.
401์ ๋ก๊ทธ์ธ ํ์(๋น์ธ์ฆ), 403์ ์ธ์ฆ์ ๋์ง๋ง ๊ถํ ์์(์ ๊ทผ ๊ฑฐ๋ถ), 404๋ ์กด์ฌํ์ง ์๋ ํ์ด์ง๋ก ์ฒ๋ฆฌํ์ธ์. 404์ 403์ ์์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ๋จ์ํ ํ์ด์ง๊ฐ ์๋๋ฐ ๊ถํ์ด ์๋ค๊ณ ์คํดํ๋ ์ผ์ด ์ค์ด๋ญ๋๋ค.


