⑦ 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到后端校验
原文地址:https://www.cnblogs.com/pleaseAnswer/p/15010613.html