Vue 前端实现登陆拦截及axios 拦截器的使用


Posted in Javascript onJuly 17, 2019

该项目是利用了Github 提供的personal token作为登录token,通过token访问你的Repository List。通过这个项目学习如何实现一个前端项目中所需要的 登录及拦截、登出、token失效的拦截及对应 axios 拦截器的使用。

准备

你需要先生成自己的 Github Personal Token( 生成Token )。 Token 生成后 访问 Demo,即可查看你的Repository List。

项目结构

├── README.md
├── dist // 打包构建后的文件夹
│ ├── build.js
│ └── build.js.map
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── css.css
│ │ ├── icon.css
│ │ └── logo.png
│ ├── constant
│ │ └── api.js // 配置api接口文件
│ ├── http.js // 封装fetch、post请求及http 拦截器配置文件
│ ├── index.vue
│ ├── login.vue
│ ├── main.js
│ ├── repository.vue
│ ├── router.js // 路由配置文件
│ └── store
│  ├── store.js 
│  └── types.js // vuex types
└── webpack.config.js

技术栈

  • Vue 2.0
  • vue-router
  • vuex
  • axios
  • vue-material

登录拦截逻辑

第一步:路由拦截

首先在定义路由的时候就需要多添加一个自定义字段 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) // 返回接口返回的错误信息
 });

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

通过上面这两步,就可以在前端实现登录拦截了。 登出 功能也就很简单,只需要把当前token清除,再跳转到首页即可。

如果想实现登陆完成之后调回到之前想要进的页面 只需在登陆页的跳转处添加如下判断

if(!!this.$route.query.redirect){
  this.$router.push(this.$route.query.redirect)//这里是拦截前想跳转的页面
 }else{
  this.$router.push('/home')//这里填你默认跳转的地址
  }

ps:下面看下vue的axios拦截器使用

axios拦截器

下载并使用axios后可以对全局进行拦截器设置。拦截器在发送请求前或响应返回时做一些特殊的处理。

下面是一个为axios添加请求loading的例子:

添加请求拦截器

//定义一个请求拦截器
axios.interceptors.request.use(function(config){
 Vue.$vux.loading.show(); //在请求发出之前进行一些操作
 return config
},function (error) {
 // 对请求错误做些什么
 // return Promise.reject(error)
});

添加响应拦截器

//定义一个响应拦截器
axios.interceptors.response.use(function(config){
 Vue.$vux.loading.hide();;//在这里对返回的数据进行处理
 return config
},function (error) {
 // 对请求错误做些什么
 // return Promise.reject(error)
});

移除拦截器

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

为axios实例添加拦截器

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

某一个函数不希望受到全局拦截器的影响

解决方法:在函数内从新添加一个拦截器

如下:为请求函数添加一个新的拦截器使之不受全局拦截器影响

const $ajax = this.$http.create()

例:下面函数不受全局拦截器影响

pollopenid(){
  const $ajax = this.$http.create()
  $ajax({
  method:'post',
  url:'',
  data:{
   
  }
  }).then(res=>{
  
  })
 }

总结

以上所述是小编给大家介绍的Vue 前端实现登陆拦截及axios 拦截器的使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
jQuery 拖动层(在可视区域范围内)
May 24 Javascript
jQuery插件 selectToSelect使用方法
Oct 02 Javascript
Jquery+asp.net后台数据传到前台js进行解析的方法
May 11 Javascript
浅析Bootstrap缩略图组件与警示框组件
Apr 29 Javascript
javascript使用闭包模拟对象的私有属性和方法
Oct 05 Javascript
canvas实现绘制吃豆鱼效果
Jan 12 Javascript
用js将long型数据转换成date型或datetime型的实例
Jul 03 Javascript
Vue学习笔记进阶篇之过渡状态详解
Jul 14 Javascript
JS 中使用Promise 实现红绿灯实例代码(demo)
Oct 20 Javascript
vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用
Apr 13 Javascript
react build 后打包发布总结
Aug 24 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
Jul 27 Javascript
初试vue-cli使用HBuilderx打包app的坑
Jul 17 #Javascript
移动端吸顶fixbar的解决方案详解
Jul 17 #Javascript
基于webpack4+vue-cli3项目实现换肤功能
Jul 17 #Javascript
js getBoundingClientRect使用方法详解
Jul 17 #Javascript
深入了解Hybrid App技术的相关知识
Jul 17 #Javascript
Vue发布项目实例讲解
Jul 17 #Javascript
Vue项目实现简单的权限控制管理功能
Jul 17 #Javascript
You might like
PHP+FastCGI+Nginx配置PHP运行环境
2014/08/07 PHP
用 Composer构建自己的 PHP 框架之构建路由
2014/10/30 PHP
PHP MSSQL 分页实例
2016/04/13 PHP
PHP设置images目录不充许http访问的方法
2016/11/01 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
javascript while语句和do while语句的区别分析
2007/12/08 Javascript
JavaScript地图拖动功能SpryMap的简单实现
2013/07/17 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
js调出上下文菜单的实例
2015/12/17 Javascript
JS实现图片延迟加载并淡入淡出效果的简单方法
2016/08/25 Javascript
D3.js实现雷达图的方法详解
2016/09/22 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
荐书|您有一份JavaScript书单待签收
2017/07/21 Javascript
bootstrap datetimepicker控件位置异常的解决方法
2017/11/23 Javascript
Echarts之悬浮框中的数据排序问题
2018/11/08 Javascript
Javascript三种字符串连接方式及性能比较
2019/05/28 Javascript
Python编程之变量赋值操作实例分析
2017/07/24 Python
Python实现生成随机数据插入mysql数据库的方法
2017/12/25 Python
Python基础教程之异常详解
2019/01/10 Python
Python将列表数据写入文件(txt, csv,excel)
2019/04/03 Python
pandas DataFrame 警告(SettingWithCopyWarning)的解决
2019/07/23 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
Python切片列表字符串如何实现切换
2020/08/06 Python
基于html5 canvas实现漫天飞雪效果实例
2014/09/10 HTML / CSS
美国最受欢迎的度假目的地优惠套餐:BookVIP
2018/09/27 全球购物
人代会标语
2014/06/30 职场文书
小学捐书活动总结
2014/07/05 职场文书
运动会加油稿20字
2014/11/15 职场文书
工会工作个人总结
2015/03/03 职场文书
2015年社区卫生工作总结
2015/04/21 职场文书
奖励通知
2015/04/22 职场文书
党员干部学习心得体会
2016/01/23 职场文书
Python实战之实现简易的学生选课系统
2021/05/25 Python
浅谈PHP7中的一些小技巧
2021/05/29 PHP
DE1107机评
2022/04/05 无线电