登入登出篇
Part 1. 登入登出行為
建立環境
- 在 components 資料夾下建立 pages 資料夾,並新增 login.vue 分頁元件
- 路由檔 (index.js) 也要加上 Login 這個
routes
- 基本登入畫面的 HTML 與 CSS 可以使用 Bootstrap 的範本
登入 API
data
新增user
帳號密碼- 透過
v-model
綁定user.username
與user.password
- 透過
@submit.prevent="signin"
觸發登入 API(.prevent
會移除預設事件)
export default {
name: 'HelloWorld',
data() {
return {
user: {
username: '',
password: '',
},
};
},
methods: {
signin() {
const api = `${process.env.APIPATH}/signin`;
const vm = this;
// 把用戶的資料傳進來
// (vm.user = 帳號 & 密碼)
this.$http.post(api, vm.user).then((response) => {
console.log(response.data);
// 回首頁
if (response.data.success) {
vm.$router.push('/'); // 如果登入成功,就會把路徑改到指定的頁面 (首頁)
}
});
},
},
};
登出 API
- 透過
@click.prevent="signout"
觸發登出 API
methods: {
signout() {
// 登出的事件
const api = `${process.env.APIPATH}/logout`;
const vm = this;
// 不需要傳入任何參數,只要觸發這個 API 就會直接登出
this.$http.post(api).then(response => {
console.log(response.data);
// 如果成功登出,就回到 Login 頁面
if (response.data.success) {
vm.$router.push("/login");
}
});
}
}
Part 2. 跨域登入驗證
這邊只紀錄前端的部分
前端 axios 請求附帶 Cookies 設定
前端其實只要加上以下片段,就能把 Cookie 正確地存在 Vue 的伺服器內。
-
修改 API 路徑
- 將登入的路徑改為
${process.env.APIPATH}/admin/signin
- 將登入的路徑改為
-
開啟 Cookies 開關 (
withCredentials
)- 在 main.js 加上
axios.defaults.withCredentials = true
,就能將withCredentials
參數設定為true
- 在 main.js 加上
加入這兩行有什麼效果呢?
主要功能是後端會自動加上 Session 並自動存在 Cookie 裡面。
這樣把 Cookies 正確存起來之後,使用者才能正確執行切換頁面等操作。
如果想要找 Session 的話,可以在 Console → Application → Cookies 裡面找到
Part 3. 驗證登入
路由元信息 (meta)
在 index.js 中,對於要驗證的頁面的路由上,加上一個判斷基準 requiresAuth
,來幫我們驗證登入狀態。
export default new VueRouter({
routes: [
{
name: 'HelloWorld',
path: '/',
component: HelloWorld,
// 判斷基準
meta: { requiresAuth: true },
},
{
name: '登入',
path: '/login',
component: Login,
},
],
});
我們這邊把 requiresAuth
放在 HelloWorld 頁面上。
當我們要從 Login 切換到 HelloWorld 頁面時,待會的 to
裡面的 meta
屬性就會有值。
Vue Router 導航守衛
在 main.js 中,透過 vue-router
提供的導航守衛,來應對路由切換的變化。
to
:即將要進入的目標路由from
:當前正要離開的路由next
:決定是否"放行"到某個路由
router.beforeEach((to, from, next) => {
console.log('to', to);
console.log('from', from);
console.log('next', next);
if (to.meta.requiresAuth) {
// 要到的頁面 (to),它的 meta 如果有 requiresAuth 的話,就"不會"直接放行
console.log('這裡需要驗證');
} else {
// 反之,若沒有 requiresAuth 的話,就會直接放行
next();
}
});
這個時候要從 Login 直接切到首頁時就會跳出需要驗證的提醒了。
接下來我們就把 if
裡面的 console.log()
換成驗證相關的程式碼。
檢查用戶是否仍持續登入
綜合以上兩點,我們就能實作出驗證使用者是否為登入狀態的功能。
我們透過驗證 API 所回傳的資訊,即 success
屬性的值,來決定是否在登入狀態下。
router.beforeEach((to, from, next) => {
// 這裡需要驗證
if (to.meta.requiresAuth) {
// 驗證用的 API 路徑
const api = `${process.env.APIPATH}/api/user/check`;
axios.post(api).then((response) => {
if (response.data.success) {
next(); // 如果成功登入就放行
} else {
// 如果不是登入狀態時,就回到登入頁面
next({
path: '/login',
});
}
});
} else {
next();
}
});
第六行因為不是在 Vue App 內,所以要使用
axios
取代this.$http
。
Part 4. 重新導向
最後我們要做一個 redirect
的功能,當輸入不存在的頁面網址時,會自動跳回指定的頁面。
redirect
我們在 index.js 中定義一個 path: '*'
的路由,並透過 redirect
轉址到 login
的頁面。
export default new VueRouter({
routes: [
{
path: '*',
redirect: 'login',
},
{
name: 'HelloWorld',
path: '/',
component: HelloWorld,
meta: {
requiresAuth: true,
}, // 判斷基準
},
{
name: '登入',
path: '/login',
component: Login,
},
],
});
因此,只要我們輸入的網址不是我們定義的 path
的話,就會被重新導向到 Login 頁面。
這麼做就能避免用戶進到不存在的頁面,而發生錯誤了。
Part 5. 後台版型
套用 Bootstrap Dashboard 版型
版型部分可以使用 Bootstrap 的範本。
首先,在 components 資料夾下新增 Dashboard.vue,並將需要的 HTML 原始碼貼進去。
同理,在 assets 資料夾下新增 _dashboard.scss,並將範本的樣式 直接貼入,並在 all.scss 內 @import
進去。
這邊要特別注意,
<template>
內要放 1 個<div>
在最外層!
最後再 import
Dashboard.vue 到路由檔案 (index.js) 中,並新增一個帶 requiresAuth
的路由。
都完成後,就能順利顯示 Dashboard 的頁面了。
新增
requiresAuth
可驗證登入狀態
版型拆解 - 元件化
將 Dashboard 的 Navbar 與 Sidebar 拆解出來,原本的 Dashboard 只留下 Main 來放自己的主要內容。
所以,我們拆解完總共會有以下三個 .vue 檔案:
- Dashboard.vue:就只是個外框
- Navbar.vue:上方選單
- Sidebar.vue:側邊選單
接著我們就可以在 Dashboard.vue 中,把 Navbar 與 Sidebar 這兩個元件 import
進來囉。
Dashboard.vue
<template>
<div>
<div class="container-fluid">
<Navbar />
<div class="row">
<Sidebar></Sidebar>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
<!-- main 換成自己的內容 -->
</main>
</div>
</div>
</div>
</template>
<script>
import Navbar from './Navbar';
import Sidebar from './Sidebar';
export default {
components: {
Navbar,
Sidebar,
},
};
</script>
動態切換載入元件
我們新增一個 Products.vue 元件放在 Main 裡面,這預計會用來做產品列表等內容。
這個 Products.vue 當然也可以用剛才的方式,直接將元件 (component) 嵌入頁面。
但是,這裡我們要試著使用 Router 的方式來設定,因為這樣做的話,我們之後還能動態地切換載入元件。
那麼,如果要動態切換元件,我們就會使用到 <router-view>
。
routerView
我們在 Dashboard.vue 的 <main>
內放入 <router-view>
。
<router-view>
是切換主要內容的區域,可以視 <router-view>
以外的區域為固定樣板,而 <router-view>
內就是每個頁面切換的內容。
這個
<router-view>
是巢狀的,因為外層的 App.vue 已經有一個了,所以 Dashboard.vue 的這個<router-view>
是內層的。
巢狀路由
巢狀的路由 (Router) 在之前有使用過,可以透過 children
陣列來完成。
{
name: 'Dashboard',
path: '/admin',
component: Dashboard,
children: [{
name: 'Products',
path: 'products',
component: Products,
meta: {
requiresAuth: true
},
}],
},
要特別注意!在官方的範例中,根路徑通常會加上
/
,子路徑則不會加上/
。
最後這裡將 meta: { requiresAuth: true }
移到 products
子路由上,確保要驗證登入過後,才能夠進入產品列表的頁面。
以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫