延續上一篇的 code,接著最關鍵的登入驗證邏輯與相關功能。

登入狀態驗證

其實就是處理各種 token 的情況,試想一下:

  • 登入成功,配發 token 給 user 保存
  • 各路由間檢查 user 的 token,失敗時就重導向登入頁並刪除 token
  • token 無誤不影響 routing
  • 登出時刪除 token

Token處理

首先寫Login.vue的 login method,驗證一組簡單帳號密碼 abcd 跟 1234:

Login.vue
1
2
3
4
5
6
7
8
9
10
11
methods: {
login(){
//write login authencation logic here!
if( this.userName == 'abcd' && this.password == '1234' ){
localStorage.setItem('token', 'ImLogin')
this.$router.push('/');
} else{
alert('login failed')
}
}
}

登入成功便寫入 localStorage 名為token值為ImLogin的 pair,之後只要檢查它就好。一般 token 會存在 cookie中,特性是能支援同網域下共用以及設定過期失效,這裡偷懶就用了 localStorage 玩玩。

同時 Header 的登出也要記得刪除 token 的動作:

Header.vue
1
2
3
4
5
6
methods: {
logout(){
localStorage.removeItem('token');
this.$router.push('/login');
}
}

檢查哨

為了讓 user 不管造訪哪一頁都要先驗證 token,只要在main.js裡替 router 物件加個beforeEach的 hook,裡面寫好驗證邏輯,就能實現造訪各路由的檢查:

main.js
1
2
3
4
5
6
7
8
9
10
11
router.beforeEach((to, from, next)=>{
const isLogin = localStorage.getItem('token') == 'ImLogin' ;
if( isLogin ){
next();
} else {
if( to.path !== '/login')
next('/login');
else
next();
}
});

其中非登入狀態的情況,要多定義一層 if else 判斷當前路由是否就在 /login 那頁再做導向,少做這層會不斷被導往 /login 直到 stack 炸掉…

beforeEach 算是 global 的檢查點,vue-router 也提供beforeRouteEnter等 hook 給 component 使用,參考這裡

您撥的號碼是空號

最後在route.js多加上這段定義,讓不存在或錯誤的路由不會再是 404,自動導向回根路徑,也能防止人亂 try 結構:

routes.js
1
2
3
4
{
path: '*',
redirect: '/',
}

大功告成

手動測看看登入系統,沒登入時永遠只會導回登入頁,就算直接輸入/userInfo也一樣。而只要有登入過,沒按登出前都能正常訪問,不用再重打。

完整的 code 都放在Github上