• ⑦ 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到后端校验
  • 相关阅读:
    MySQL的char和varchar针对空格的处理
    单KEY业务,数据库水平切分架构实践
    接口测试学习笔记1-接口测试的用例设计
    Robot Framework源码解析(2)
    Robot Framework 源码解析(1)
    Python学习笔记1 -- TypeError: 'str' object is not callable
    OKHttp源码学习同步请求和异步请求(二)
    OKHttp源码学习--HttpURLConnection HttpClient OKHttp Get and post Demo用法对比
    Javapoet源码解析
    Universal-Image-Loader源码解解析---display过程 + 获取bitmap过程
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15010613.html
Copyright © 2020-2023  润新知