借助axios的拦截器实现Vue.js中登陆状态校验

axios介绍

什么是axios

axios是一个基于Promise的HTTP库,可以用在浏览器或node.js中。

axios特点:

  1. 从浏览器中创建XMLHTTPRequest
  2. 从node.js端创建http请求
  3. 支持PromiseAPI
  4. 拦截请求和响应
  5. 转换请求数据和响应数据
  6. 取消请求
  7. 自动转换JSON数据
  8. 客户端支持防御XSRF

axios拦截器

为什么使用拦截器

页面发送http请求,很多情况我们要对请求和其响应进行特定的处理;例如每个请求都附带后端返回的token,拿到response之前loading动画的展示等。如果请求数非常多,这样处理起来会非常的麻烦,程序的优雅性也会大打折扣。在这种情况下,axios为开发者提供了这样一个API:拦截器。拦截器分为 请求(request)拦截器和 响应(response)拦截器。

  1. 在请求和响应被then或catch处理前拦截它们。
//添加请求拦截器
axios.interceptors.request.use(function(config){
  //在请求发送之前做些什么
  return config
},function(error){
  //对请求错误做些什么
  return Promise.reject(error)
})
//添加响应请求
axios.interceptors.reponse.use(function(reponse){
  //对响应数据做些什么
  return reponse
},function(error){
  //对响应错误做些什么
  return Promise.reject(error)
})
  1. 添加拦截器使用use
  2. 移除拦截器使用eject
var myInterceptors = axios.interceptors.request.use()
//移除拦截器
axios.interceptors.request.eject(myInterceptors)
  1. axios自定义实例添加拦截器
//自定义实例
var instance = axios.create()
//添加拦截器
instance.interceptors.request.use()

axios取消请求

  1. 使用cancel token取消请求
  2. 可以使用 CancelToken.source 工厂方法创建 cancel token,
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
  1. 还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:
var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();

借助axios的拦截器实现Vue.js中登陆状态校验

后台系统中,不是每个页面都需要登录权限,所以要对需要进行登录权限的页面做好标记,使用路由的meta标签

{
  path: '/userInfo',
  name: '/userInfo',
  meta: {
    requireAuth: true // 该路由需要登录权限校验
  },
  component: userInfo
},{
  path: '/userInfo',
  name: '/userInfo',
  // 该路由需要登录权限校验
  component: userInfo
}

定义一起全局前置守卫,每次跳转路由,进行权限校验

router.beforeEach((to,from,next) => {
  if(to.meta.requireAuth){ //如果路由需要校验权限
  /*
    从vuex拿出token码,说明已经登录
    (前端的Token可以伪造,并不靠谱)
  */
    if(store.state.token){
      next() //正常跳转页面
    }else{
      next({
        path: "/login",
        query: {redirect: to.fullPath}
        /*将跳转的路由地址作为参数带给登录页,登录成功后跳转回改页面 */
      })
    }
  }else {
    //如果不要校验,直接进入登录页
    next()
  }
})

但以上的实现存在问题,token可以伪造,这是其一,其二,token前端存在,但后端可能已经失效。所以采用后端的一层校验,确保权限token的准确性。就要使用到axios中的拦截器(interceptors)。

实现思路:如果前端有token ,每次发送请求的时候,把token 发送给后端,后端按到token后,进行校验,之后把校验结果在接口中反馈
请求拦截:

axios.interceptors.request.use(requestConfig => {
  if(store.state.token){
    config.headers.Authorization = ${store.state.token}
  }
  return requestConfig
},err => {
  return Promise.reject(err)
})

响应拦截:后端拿到Token,发现token ,返回401(前后端约定好的),此时前端就知道作何处理

// response interceptor
axios.interceptors.response.use(
    response => {
        // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
        // 否则的话抛出错误
        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
            return Promise.reject(response);
        }
    },
    // 服务器状态码不是2开头的的情况
    // 这里可以跟你们的后台开发人员协商好统一的错误状态码
    // 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等
    // 下面列举几个常见的操作,其他需求可自行扩展
    error => {
        if (error.response.status) {
            switch (error.response.status) {
                // 401: 未登录
                // 未登录则跳转登录页面,并携带当前页面的路径
                // 在登录成功后返回当前页面,这一步需要在登录页操作。
                case 401:
                    router.replace({
                        path: '/login',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                    break;

                // 403 token过期
                // 登录过期对用户进行提示
                // 清除本地token和清空vuex中token对象
                // 跳转登录页面
                case 403:
                      Message({
                        message: '登录过期,请重新登录',
                        duration: 1000,
                        forbidClick: true
                    });
                    // 清除token
                    localStorage.removeItem('token');
                    store.commit('loginSuccess', null);
                    // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
                    setTimeout(() => {
                        router.replace({
                            path: '/login',
                            query: {
                                redirect: router.currentRoute.fullPath
                            }
                        });
                    }, 1000);
                    break;

                // 404请求不存在
                case 404:
                    Message({
                        message: '网络请求不存在',
                        duration: 1500,
                        forbidClick: true
                    });
                    break;
                // 其他错误,直接抛出错误提示
                default:
                    Message({
                        message: error.response.data.message,
                        duration: 1500,
                        forbidClick: true
                    });
            }
            return Promise.reject(error.response);
        }
    }
});

对于token

token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候,会首先从本地存储中读取token,如果token存在说明用户已经登陆过,则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,服务器就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345