vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)


Posted in Javascript onOctober 24, 2018

一、路由拦截

登录拦截逻辑

第一步:路由拦截

首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。如果用户已经登录,则顺利进入路由,

否则就进入登录页面。

const routes = [
  {
    path: '/',
    name: '/',
    component: Index
  },
  {
    path: '/repository',
    name: 'repository',
    meta: {
      requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
    },
    component: Repository
  },
  {
    path: '/login',
    name: 'login',
    component: Login
  }
];

定义完路由后,我们主要是利用vue-router提供的钩子函数beforeEach()对路由进行判断。

router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
    if (store.state.token) { // 通过vuex state获取当前的token是否存在
      next();
    }
    else {
      next({
        path: '/login',
        query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
      })
    }
  }
  else {
    next();
  }
})

每个钩子方法接收三个参数:

* to: Route: 即将要进入的目标 路由对象
* from: Route: 当前导航正要离开的路由
* next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
* next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
* next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
* next(‘/') 或者 next({ path: ‘/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

确保要调用 next 方法,否则钩子就不会被 resolved。

完整的方法见/src/router.js

其中,to.meta中是我们自定义的数据,其中就包括我们刚刚定义的requireAuth字段。通过这个字段来判断该路由是否需要登录权限。需要的话,同时当前应用不存在token,则跳转到登录页面,进行登录。登录成功后跳转到目标路由。

登录拦截到这里就结束了吗?并没有。这种方式只是简单的前端路由控制,并不能真正阻止用户访问需要登录权限的路由。还有一种情况便是:当前token失效了,但是token依然保存在本地。这时候你去访问需要登录权限的路由时,实际上应该让用户重新登录。

这时候就需要结合 http 拦截器 + 后端接口返回的http 状态码来判断。

第二步:拦截器

要想统一处理所有http请求和响应,就得用上 axios 的拦截器。通过配置http response inteceptor,当后端接口返回401 Unauthorized(未授权),让用户重新登录。

// http request 拦截器
axios.interceptors.request.use(
  config => {
    if (store.state.token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
      config.headers.Authorization = `token ${store.state.token}`;
    }
    return config;
  },
  err => {
    return Promise.reject(err);
  });
// http response 拦截器
axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // 返回 401 清除token信息并跳转到登录页面
          store.commit(types.LOGOUT);
          router.replace({
            path: 'login',
            query: {redirect: router.currentRoute.fullPath}
          })
      }
    }
    return Promise.reject(error.response.data)  // 返回接口返回的错误信息
  });

二、http拦截

拦截器

首先我们要明白设置拦截器的目的是什么,当我们需要统一处理http请求和响应时我们通过设置拦截器处理方便很多.

这个项目我引入了element ui框架,所以我是结合element中loading和message组件来处理的.我们可以单独建立一个http的js文件处理axios,再到main.js中引入.

/**
 * http配置
 */
// 引入axios以及element ui中的loading和message组件
import axios from 'axios'
import { Loading, Message } from 'element-ui'
// 超时时间
axios.defaults.timeout = 5000
// http请求拦截器
var loadinginstace
axios.interceptors.request.use(config => {
 // element ui Loading方法
 loadinginstace = Loading.service({ fullscreen: true })
 return config
}, error => {
 loadinginstace.close()
 Message.error({
 message: '加载超时'
 })
 return Promise.reject(error)
})
// http响应拦截器
axios.interceptors.response.use(data => {// 响应成功关闭loading
 loadinginstace.close()
 return data
}, error => {
 loadinginstace.close()
 Message.error({
 message: '加载失败'
 })
 return Promise.reject(error)
})
export default axios

这样我们就统一处理了http请求和响应的拦截.当然我们可以根据具体的业务要求更改拦截中的处理.

vue2+element更全面,更简单深入的例子 请查看:https://github.com/guo11111/vue2-demo

总结

以上所述是小编给大家介绍的vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery实现浮动层随浏览器滚动条滚动的方法
Sep 22 Javascript
微信小程序 video组件详解
Oct 25 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
Dec 23 Javascript
JS中定位 position 的使用实例代码
Aug 06 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
Jun 20 jQuery
Vue2.0 v-for filter列表过滤功能的实现
Sep 07 Javascript
React降级配置及Ant Design配置详解
Dec 27 Javascript
vue+iview 兼容IE11浏览器的实现方法
Jan 07 Javascript
JavaScript学习笔记之数组基本操作示例
Jan 09 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
Jun 19 Javascript
javascript事件监听与事件委托实例详解
Aug 16 Javascript
基于vue实现图片验证码倒计时60s功能
Dec 10 Javascript
vue 属性拦截实现双向绑定的实例代码
Oct 24 #Javascript
深入理解JavaScript的值传递和引用传递
Oct 24 #Javascript
详解JavaScript中typeof与instanceof用法
Oct 24 #Javascript
使用electron实现百度网盘悬浮窗口功能的示例代码
Oct 24 #Javascript
JavaScript根据json生成html表格的示例代码
Oct 24 #Javascript
vue项目引入Iconfont图标库的教程图解
Oct 24 #Javascript
vue中的router-view组件的使用教程
Oct 23 #Javascript
You might like
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
php SQL Injection with MySQL
2011/02/27 PHP
PHP中用hash实现的数组
2011/07/17 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
2013/07/01 PHP
php发送post请求函数分享
2014/03/06 PHP
php使用ob_flush不能每隔一秒输出原理分析
2015/06/02 PHP
php源码分析之DZX1.5加密解密函数authcode用法
2015/06/17 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
PHP的AES加密算法完整实例
2016/07/20 PHP
jquery 循环显示div的示例代码
2013/10/18 Javascript
ie8模式下click无反应点击option无反应的解决方法
2014/10/11 Javascript
jQuery循环遍历子节点并获取值的方法
2016/04/14 Javascript
关于Javascript回调函数的一个妙用
2016/08/29 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
2019/05/16 Javascript
基于JavaScript实现单例模式
2019/10/30 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
在Python的web框架中配置app的教程
2015/04/30 Python
Python中基本的日期时间处理的学习教程
2015/10/16 Python
Python编程修改MP3文件名称的方法
2017/04/19 Python
python爬虫实战之爬取京东商城实例教程
2017/04/24 Python
Python基础教程之利用期物处理并发
2018/03/29 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
python递归法解决棋盘分割问题
2019/07/17 Python
详解Anconda环境下载python包的教程(图形界面+命令行+pycharm安装)
2019/11/11 Python
如何安装并在pycharm使用selenium的方法
2020/04/30 Python
基于Keras中Conv1D和Conv2D的区别说明
2020/06/19 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
Python应用自动化部署工具Fabric原理及使用解析
2020/11/30 Python
css3制作彩色边线3d立体按钮的示例(css3按钮)
2014/05/06 HTML / CSS
澳大利亚先进的皮肤和激光诊所购物网站:Soho Skincare
2018/10/15 全球购物
农药学硕士毕业生自荐信
2013/09/25 职场文书
后勤服务中心总经理工作职责
2014/03/03 职场文书
大型会议策划方案
2014/05/17 职场文书
学校先进集体事迹材料
2014/05/31 职场文书
初中军训感想
2015/08/07 职场文书