vue登录态管理=+路由守卫+封装 Axios+Vuex

vue登录态管理=+路由守卫+封装 Axios+Vuex,第1张

1.理由配置

路由的配置path时;在需要守卫的path加上meta属性;

{
    path: '/home',
    component: home,
    meta:{requireAuth:true}
}

在路由配置文件中加上

//路由配置文件
import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from './routes';
//使用VueRouter插件
Vue.use(VueRouter);
//引入store 
import store from '@/store';


//先保存一份VueRouter
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写push|replace
//第一个参数:往哪里跳(传递哪些参数)
/** 
 * call 和 apply 区别
 *  相同点:都可以调用函数一次,都可以篡改函数的上下文一次
 *  不同点:call与app传递参数用逗号隔开,apply方法执行,传递数组
 */
VueRouter.prototype.push = function(location,resolve,reject) {
    if(resolve && reject) {
        originPush.call(this,location,resolve,reject);
    } else {
        originPush.call(this,location,()=>{},()=>{});
    }
}
VueRouter.prototype.replace = function(location,resolve,reject) {
    if(resolve && reject) {
        originReplace.call(this,location,resolve,reject);
    } else {
        originReplace.call(this,location,()=>{},()=>{});
    }
}

//配置路由
 let router = new VueRouter({
    //路由配置
    routes,
    scrollBehavior (to,from,savedPosition) {
        return {y:0}
    }
});

//理由全局守卫,前置守卫(跳转之前判断)
router.beforeEach(async(to,from,next) => {
    // next();
    //获取token
    let token = store.state.user.token;
    let name = store.state.user.userInfo.name;
    if(token) {
        //用户已经登录
        if(to.path == '/login') {
            next('/home');
        }else{
            if(name){
                next(); 
            } else {
                try{
                    await store.dispatch('getUserInfo');
                    next();
                } catch(error) {
                    //清楚token
                    await store.dispatch('userLogout');
                    next('/login');
                }
            }
        }
    } else {
        // 用户未登录
        let toPath = to.path;
        if(toPath.indexOf('/trade') != -1 || 
            toPath.indexOf('/pay') != -1 || 
            toPath.indexOf('/pausuccess') != -1 || 
            toPath.indexOf('/center') != -1||
            toPath.indexOf('/Search') != -1||
            toPath.indexOf('/shopcart') != -1
            ) {
            next('/login');
        } else {
            next();
        }
    }
});

export default router;

这里的只是限制了用户访问时路由页面的跳转(说白了,只是为了改善用户体验,并不能达到安全发目的),

更加安全的防护主要在后台完成。

2.封装 Axios 请求

为什么要 Axios?

每次请求时需要携带token到后台,进行身份认证;项目需要根据响应回来的自定义状态码,决定是否跳转到登陆页面。

        需要设置withCredentials为true。另外,在利用vue-router进行重定向时,设置登陆页面的地址,以及登陆完成后需要重定向的页面的地址。

//axios 进行二次封装
//引入axios
import axios from "axios";
//在当前模块引入store
import store from '@/store';
//引入进度条 和 进度条样式  * 非必须
import nprogress from 'nprogress';
import 'nprogress/nprogress.css';

//1.利用axios对象的方法create,去创建一个axios实例
//2.这里requests就是axios,只不过稍微配置一下
const requests = axios.create({
     //配置对象
     //基础路径,发请求的时候,路径中会出现api
     baseURL:"/api",
     //请求超时的时间为5s
     timeout:5000,
 });
// 请求拦截器:在发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use((config)=>{
    if(store.state.detail.uuid_token) {
        config.headers.userTempId = store.state.detail.uuid_token;
    }
    //需要携带token带给服务器
    if(store.state.user.token) {
        config.headers.token = store.state.user.token;
    }
    //进度条开始
    nprogress.start();
    return config;
});
//相应拦截器
requests.interceptors.response.use((res)=>{
    //成功回调
    //进度条结束
    nprogress.done();
    return res.data;
},(error)=>{
    //失败回调
    new Promise.reject(new Error('faile'));
    
});




export default requests;

3.Vuex

 localStorage是没有响应式的,这里需要和Vuex配合使用;

或者说Vuex作为桥梁

import {reqGetCode,reqUserRegister,reqUserLogin,reqUserInfo,reqLogout} from '@/api';
import {setToken,getToken,removeToken} from '@/utils/token'

//home模块“小”仓库

//state:数据仓库
const state = {
    code:'',
    token:getToken(),
    userInfo:{}
}

//actions:可以处理自己的业务逻辑,也可以异步
const actions = {
    //获取验证码
    async getCode({commit},phone) {
       let result = await reqGetCode(phone);
    //    console.log(result)
       if(result.code == 200 ){
           commit("GETCODE",result.data);
           return "ok";
       } else {
           return Promise.reject(new Error('faile'));
       }
    },
    //用户注册
    async userRegister({commit},user){
        let result = await reqUserRegister(user);
        if(result.code == 200 ) {
            return 'ok';
        } else {
            return Promise.reject(new Error(result.message));
        }

    },
    //登陆业务
    async userLogin({commit},data) {
        let result = await reqUserLogin(data);
        if(result.code == 200) { 
            commit('USERLOGIN',result.data.token);
            //持久化存储token
            setToken(result.data.token);
            return 'ok';
        } else {
            return Promise.reject(new Error(result.message));
        }
    },
    //获取用户信息
    async getUserInfo({commit}) {
        let result = await reqUserInfo();
        if(result.code == 200) { 
            commit('GETUSERINFO',result.data);
            return 'ok';
        } else {
            return Promise.reject(new Error(result.message));
        }
    },
    //退出登录
    async userLogout({commit}) {
        let result = await reqLogout();
        if(result.code == 200) {
            commit('CLEAR');
            return 'ok';
        } else {
            return Promise.reject(new Error(result.message));
        }
    }
}

const mutations = {
    GETCODE(state,code) {
        state.code = code;
    },
    USERLOGIN(state,token) {
        state.token = token;
    },
    GETUSERINFO(state,userInfo) {
        state.userInfo = userInfo;
    },
    //清楚本地用户数据
    CLEAR(state) {
        state.token = '';
        state.userInfo = {};
        removeToken();
    }
    
}


export default {
    state,
    mutations,
    actions,
    getters,
}
4.存储Token
//存token
export const setToken = (token) => {
    localStorage.setItem('TOKEN',token);
}
//取token
export const getToken = () => {
    return localStorage.getItem('TOKEN');
}
//清除token
export const removeToken = () => {
    localStorage.removeItem('TOKEN');
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/990722.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存