๋ก๊ทธ์ธ ํ์ด์ง์ ๊ฐ์
ํ๊ธฐ ํ์ด์ง ์ธ ๋ค๋ฅธ ํ์ด์ง๋ค์ ์ธ์ฆ๋ ์ ์ ๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก
navigation guard ๋ฅผ ์ค์ ํด์ค๊ฑฐ์
routes ์ register ์ login ์ ์ธํ ๋๋จธ์ง ํ์ด์ง์
requireAuth: true,
๋ฅผ ์ถ๊ฐํ๋ค.
const routes = [
{
path: "/",
component: Home,
title: "ํ",
icon: "fas fa-home fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/",
component: Home,
title: "ํ์ํ๊ธฐ",
icon: "fas fa-hashtag fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/notifications",
component: Notifications,
title: "์๋ฆผ",
icon: "far fa-bell fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/messages",
component: Messages,
title: "์ชฝ์ง",
icon: "far fa-envelope fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/",
component: Home,
title: "๋ถ๋งํฌ",
icon: "far fa-bookmark fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/",
component: Home,
title: "๋ฆฌ์คํธ",
icon: "far fa-list-alt fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/profile",
component: Profile,
title: "ํ๋กํ",
icon: "far fa-user fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/",
component: Home,
title: "๋๋ณด๊ธฐ",
icon: "fas fa-ellipsis-h fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout", requireAuth: true },
},
{
path: "/register",
component: Register,
meta: { isMenu: false, layout: "EmptyLayout" },
},
{
path: "/login",
component: Login,
meta: { isMenu: false, layout: "EmptyLayout" },
},
];
const routes = [
{
path: "/",
component: Home,
title: "ํ",
icon: "fas fa-home fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/",
component: Home,
title: "ํ์ํ๊ธฐ",
icon: "fas fa-hashtag fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/notifications",
component: Notifications,
title: "์๋ฆผ",
icon: "far fa-bell fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/messages",
component: Messages,
title: "์ชฝ์ง",
icon: "far fa-envelope fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/",
component: Home,
title: "๋ถ๋งํฌ",
icon: "far fa-bookmark fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/",
component: Home,
title: "๋ฆฌ์คํธ",
icon: "far fa-list-alt fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/profile",
component: Profile,
title: "ํ๋กํ",
icon: "far fa-user fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/",
component: Home,
title: "๋๋ณด๊ธฐ",
icon: "fas fa-ellipsis-h fa-fw text-2xl",
meta: { isMenu: true, layout: "DefaultLayout" },
requireAuth: true,
},
{
path: "/register",
component: Register,
meta: { isMenu: false, layout: "EmptyLayout" },
},
{
path: "/login",
component: Login,
meta: { isMenu: false, layout: "EmptyLayout" },
},
];
router.beforeEach((to, from, next) => {
console.log(to);
// not authenticated
// router.push("/login")
// authenticated
next();
});
๋ฉ์ธํ์ด์ง์์ ์ฝ์์ ํ์ธํด๋ณด๋ฉด
matched -> 0 -> meta -> requireAuth๊ฐ true์ธ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด๊ฑธ ์ด์ฉํด์ ๋ค๋น๊ฒ์ด์
๊ฐ๋๋ฅผ ๋ง๋ค๊ฒ์
ํ์ฌ ์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค.
๊ทธ๋ฆฌ๊ณ DefaultLayout ์์
๋๋กญ๋ค์ด ๋ฉ๋ด๋ฅผ ์ถ๊ฐํ๋ค.
<!-- ํ๋กํ ๋๋กญ๋ค์ด ๋ฉ๋ด -->
<div
class="absolute bottom-20 left-12 shadow rounded-lg w-70"
v-if="showProfileDropdown"
@click="showProfileDropdown = false"
>
<button
class="hover:bg-gray-50 border-b border-gray-100 flex p-3 w-full items-center"
>
<div class="mx-4">
<div class="font-bold text-sm">dmsdl8917@ddddddd.com</div>
<div class="text-left text-sm text-gray-500">@joeuni</div>
</div>
<i class="fas fa-check text-primary ml-auto"></i>
</button>
<button
class="hover:bg-gray-50 p-3 w-full text-left text-sm"
@click="onLogout"
>
@joeuni ๊ณ์ ์์ ๋ก๊ทธ์์
</button>
</div>
</div>
</template>
์๋์ ํ๋กํ์ ํด๋ฆญํ๋ฉด ์๋ก ๋๋กญ๋ค์ด์ด ํผ์ณ์ง๊ฒ ๋ง๋ค๊ฑฐ๋ผ์
ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
const showProfileDropdown = ref(false);
๋ฆฌํด์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด์ฃผ๊ณ
return { routes, showProfileDropdown, onLogout };
},
};
<!-- ํ๋กํ ๋ฒํผ -->
<div class="xl:mr-3 mb-3" @click="showProfileDropdown = true">
<button
ํ๋กํ๋ฒํผ์ ํด๋ฆญํ๋ฉด showProfileDropdown ์ด true๋ก ๋ณ๊ฒฝ๋๊ฒ ํด๋ฆญํจ์๋ฅผ ์ถ๊ฐํ๋ค.
<!-- ํ๋กํ ๋๋กญ๋ค์ด ๋ฉ๋ด -->
<div
class="absolute bottom-20 left-12 shadow rounded-lg w-70"
v-if="showProfileDropdown"
@click="showProfileDropdown = false"
>
๋๋กญ๋ค์ด์ v-if๋ก showProfileDropdown์ด true์ผ ๋๋ง ๋ณด์ฌ์ฃผ๊ณ
๋ค์ ํด๋ฆญํ๋ฉด false๋ก ๋ณ๊ฒฝํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์์ ๋ฒํผ์ํด๋ฆญํ๋ฉด onLogoutํจ์๊ฐ ์คํ๋๊ฒ ํ๋ค.
<button
class="hover:bg-gray-50 p-3 w-full text-left text-sm"
@click="onLogout"
>
@joeuni ๊ณ์ ์์ ๋ก๊ทธ์์
</button>
import { signOut } from "firebase/auth";
import { auth } from "../firebase";
import store from "../store";
๋ก๊ทธ์์ ํจ์๋ auth๋ก ๋ก๊ทธ์์์ ์คํํ๊ณ
store์ ํ์ฌ ๋ก๊ทธ์ธ ์ค์ธ ์ ์ ๋ฅผ null๋ก ๋ณ๊ฒฝํ๋ค
๊ทธ ๋ค router.replace๋ก loginํ์ด์ง๋ก ์ด๋์ํด
//๋ก๊ทธ์์ ํจ์
const onLogout = async () => {
await signOut(auth);
store.commit("SET_USERS", null);
await router.replace("./login");
};
return { routes, showProfileDropdown, onLogout };
https://firebase.google.com/docs/auth/web/password-auth?hl=ko&_gl=1*k88n5b*_up*MQ..*_ga*NTI3NzMyNTQwLjE3MTA5MzMyNzA.*_ga_CW55HF8NVT*MTcxMDkzMzI3MC4xLjAuMTcxMDkzMzI3MC4wLjAuMA..
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ฐ๋ฒํธ ๊ธฐ๋ฐ ๊ณ์ ์ผ๋ก Firebase์ ์ธ์ฆํ๊ธฐ
์๊ฒฌ ๋ณด๋ด๊ธฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ฐ๋ฒํธ ๊ธฐ๋ฐ ๊ณ์ ์ผ๋ก Firebase์ ์ธ์ฆํ๊ธฐ ์ปฌ๋ ์
์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ
์ธ ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฅํ์ธ์. Firebase ์ธ์ฆ์ ์ฌ์ฉํด์
firebase.google.com