⑦ vue-router 用户权限控制

如何做才能限制要登录之后才能访问?

路由元信息

  • 给路由存放信息

用户权限控制

用路由守卫-- next() 可以控制组件是否可以被访问

1. 定义路由元信息,确定哪个路由需要登陆权限

router > index.js

{
  name: 'cart',
  path: '/cart',
  component: Cart,
  meta: { requiresAuth: true }
}

2. 进入路由后,确认用户是否登录

  • 全局路由守卫中做判断

如何实现登陆后跳回原页面?

  • query & this.$router
  1. 登录则放行 -- [暂时]

  2. 否则跳转至登录界面并传递目标路由地址

app > routers > index.js -- 确认用户是否登录

router.beforeEach((to,from,next) => {
    // 判断当前路由是否需要路由权限
    if(to.meta.requiresAuth) {
        //获取tokenlet 
        Authorization = localStorage.getItem('Authorization');
        if(Authorization) {
            //登录则放行
            next();
        } else {
            //否则跳转到登录页面
            //同时传递路由地址 -- 为了登录后能够再次返回
            // router.push('/login');
            next({
                path: '/login',
                query: {
                    redirectUrl: to.fullPath
                }
            });
        }
    } else {
        next();
    }
})

Login.vue -- 实现登录后跳回购物车 or我的

   // 获取token并保存到本地
   let Authorization = data.data;
   localStorage.setItem('Authorization', Authorization);
   //实现登录后跳回购物车or我的
   console.log(this.$route.query);
   let { redirectUrl } = this.$route.query || '/mine';
   this.$router.replace(redirectUrl);

3. 校验 token 的有效性

  1. 是否过期

  2. 是否被篡改

token.js

function verify(token) {
    let result;
    try {
        //解密
        var decoded = jwt.verify(token, secretKey);
        console.log('verify', decoded);
        result = true;
    } catch(err) {
        // err
        result = false;
    }
    return result;
}

database > routers > index.js

Router.get('/verify', (req,res) => {
    //获取请求头上的token
    let Authorization = req.get('Authorization');
    if(token.verify(Authorization)) {
        res.send(formatData())
    } else {
        res.send(formatData({status:0}))
    }
});

app > routers > index.js -- 发送校验请求

router.beforeEach((to,from,next) => {
    //判断当前路由是否需要路由权限
    if(to.meta.requiresAuth) {
        //获取token
        let Authorization = localStorage.getItem('Authorization');
        if(Authorization) {
            //登录则放行
            next(); 
            //先放行,后期校验不通过再返回
            //发送校验请求--校验接口
            router.app.axios.get('http://localhost:1910/verify', {
                headers: {
                    Authorization
                }
            }).then(({ data }) => {
                console.log('校验结果:', data);
                if(data.status == 0) {
                    //跳转到登录页面
                    next({
                        path: '/login',
                        query: {
                            redirectUrl: to.fullPath
                        }
                    });
                }
            })
        } else {
            //否则跳转到登录页面
            //同时传递路由地址 -- 为了登录后能够再次返回
            // router.push('/login');
            next({
                path: '/login',
                query: {
                    redirectUrl : to.fullPath
                }
            });
        }
    } else {
        next();
    }
})

如何实现下次免登录?

  • token 令牌

[在后端加密]

1. 第一次用户登录,后端校验通过则生成一个 token,并返回给客户端

  • 借助第三方工具 --- jsonwebtoken

  • token.js ---创建 token

const secretKey = 'zhoutest'; //密钥
/**加密--创建token
 *
 * @param {Object} data 加密的数据
 * @param {Number|String} expirseIn 有效期
 * @return {String} 返回token
 */
 function create(data, expiresIn=20) {
    let token = jwt.sign(
        data,
        secretKey, //密钥
        { expiresIn } //有效期(单位:s)
    );
    return token;
}
// login.js--将数据加密后生成的token,通过data传到客户端[前后端数据统一格式]
const { formatData, token } = require('../utils');
const colName='user';
Router.get('/', async (req, res)=>{
    let { username, password } = req.query;
    let data = await find(colName, { username, password })
    if(data.length > 0) {
        //登录成功创建一个令牌
        let Authorization = token.create({username});
        res.send( formatData({ data: Authorization })); 
    } else {
        res.send(formatData({ status:0 }))
    }
})

2. 客户端接收到 token,保存到本地

  • Login.vue -- 保存
  // 获取token并保存到本地
  let Authorization  = data.data;
  localStorage.setItem('Authorization', Authorization);

3. 在需要登陆权限的页面,自动发送 token 到后端校验

posted on 2021-07-14 14:22  pleaseAnswer  阅读(565)  评论(0编辑  收藏  举报