Vue中的验证登录状态的实现方法

Vue项目中实现用户登录及token验证

先说一下我的实现步骤:

  1. 使用easy-mock新建登录接口,模拟用户数据
  2. 使用axios请求登录接口,匹配账号和密码
  3. 账号密码验证后, 拿到token,将token存储到sessionStorage中,并跳转到首页
  4. 前端每次跳转时,就使用导航守卫(vue-router.beforeEach)判断 sessionStorage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面。
  5. 注销后,就清除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 ;
    axios.get( 'https://easy-mock.com/mock/5c7cd0f89d0184e94358d/museum/login' ).then(response=>{
     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。

猜你喜欢

转载自www.cnblogs.com/fiona383/p/10841778.html