Vue項目中實現用戶登錄及token驗證
先說一下我的實現步驟:
- 使用easy-mock新建登錄接口,模擬用戶數據
- 使用axios請求登錄接口,匹配賬號和密碼
- 賬號密碼驗證后, 拿到token,將token存儲到sessionStorage中,並跳轉到首頁
- 前端每次跳轉時,就使用導航守衛(vue-router.beforeEach)判斷 sessionStorage 中有無 token ,沒有就跳轉到登錄頁面,有則跳轉到對應路由頁面。
- 注銷后,就清除sessionStorage里的token信息並跳轉到登錄頁面
使用easy-mock模擬用戶數據
我用的是easy-mock,新建了一個接口,用於模擬用戶數據:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
{
"error_code"
: 0,
"data"
: [{
"id"
:
'1'
,
"usertitle"
:
"管理員"
,
"username"
:
"admin"
,
"password"
:
"123456"
,
"token"
:
"@date(T)"
,
},
{
"id"
:
'2'
,
"usertitle"
:
"超級管理員"
,
"username"
:
"root"
,
"password"
:
"root"
,
"token"
:
"@date(T)"
,
}
]
}
|
login.vue中寫好登陸框:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<template>
<div>
<p>用戶名:<input type=
'text'
v-model=
"userName"
></p>
<p>密碼:<input type=
'text'
v-model=
"passWord"
></p>
<button @click=
"login()"
>登錄</button>
</div>
</template>
<script>
export
default
{
data() {
return
{
userName:
'root'
,
passWord:
'root'
}
}
}
</script>
|
然后下載axios:npm install axios --save,用來請求剛剛定義好的easy-mock接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
login(){
const self =
this
;
var
res =response.data.data,
len = res.length,
userNameArr= [],
passWordArr= [],
ses= window.sessionStorage;
// 拿到所有的username
for
(
var
i=0; i<len; i++){
userNameArr.push(res[i].username);
passWordArr.push(res[i].password);
}
console.log(userNameArr, passWordArr);
if
(userNameArr.indexOf(
this
.userName) === -1){
alert(
'賬號不存在!'
);
}
else
{
var
index = userNameArr.indexOf(
this
.userName);
if
(passWordArr[index] ===
this
.passWord){
// 把token放在sessionStorage中
ses.setItem(
'data'
, res[index].token);
this
.$parent.$data.userTitle = res[index].usertitle;
//驗證成功進入首頁
this
.startHacking (
'登錄成功!'
);
//跳轉到首頁
this
.$router.push(
'/index'
);
// console.log(this.$router);
}
else
{
alert(
'密碼錯誤!'
)
}
}
}).
catch
(err=>{
console.log(
'連接數據庫失敗!'
)
})
}
|
這一步最重要的是當賬號密碼正確時,把請求回來的token放在sessionStorage中,
配置路由
然后配置路由新加一個meta屬性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
{
path:
'/'
,
name:
'login'
,
component: login,
meta:{
needLogin:
false
}
},
{
path:
'/index'
,
name:
'index'
,
component: index,
meta:{
needLogin:
true
}
}
|
判斷每次路由跳轉的鏈接是否需要登錄,
導航衛士
在main.js中配置一個全局前置鈎子函數:router.beforeEach(),他的作用就是在每次路由切換的時候調用
這個鈎子方法會接收三個參數:to、from、next。
- to:Route:即將要進入的目標的路由對象,
- from:Route:當前導航正要離開的路由,
- next:Function:個人理解這個方法就是函數結束后執行什么,先看官方解釋
- 1.next():進行管道中的下一個鈎子。如果全部鈎子執行完了,則導航的狀態就是confirmed(確認的),
- 2.next(false):中斷當前的導航。如果瀏覽器的url改變了(可能是用戶手動或瀏覽器后退按鈕),那么url地址會重置到from路由對應的地址。
- 3.next('/')或next({path:'/'}):跳轉到一個不同的地址。當前導航被中斷,進入一個新的導航。
用sessionStorage存儲用戶token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//路由守衛
router.beforeEach((to, from, next)=>{
//路由中設置的needLogin字段就在to當中
if
(window.sessionStorage.data){
console.log(window.sessionStorage);
// console.log(to.path) //每次跳轉的路徑
if
(to.path ===
'/'
){
//登錄狀態下 訪問login.vue頁面 會跳到index.vue
next({path:
'/index'
});
}
else
{
next();
}
}
else
{
// 如果沒有session ,訪問任何頁面。都會進入到 登錄頁
if
(to.path ===
'/'
) {
// 如果是登錄頁面的話,直接next() -->解決注銷后的循環執行bug
next();
}
else
{
// 否則 跳轉到登錄頁面
next({ path:
'/'
});
}
}
})
|
這里用了router.beforeEach vue-router導航守衛
每次跳轉時都會判斷sessionStorage中是否有token值,如果有則能正常跳轉,如果沒有那么就返回登錄頁面。
注銷
至此就完成了一個簡單的登錄狀態了,瀏覽器關閉后sessionStorage會清空的,所以當用戶關閉瀏覽器再打開是需要重新登錄的
當然也可以手動清除sessionStorage,清除動作可以做成注銷登錄,這個就簡單了。
1
2
3
4
5
6
|
loginOut(){
// 注銷后 清除session信息 ,並返回登錄頁
window.sessionStorage.removeItem(
'data'
);
this
.common.startHacking(
this
,
'success'
,
'注銷成功!'
);
this
.$router.push(
'/index'
);
}
|
寫一個清除sessionStorag的方法。
一個簡單的保存登錄狀態的小Demo。