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 相关文章推荐
JavaScript 验证浏览器是否支持javascript的方法小结
May 17 Javascript
jquery 学习之二 属性 文本与值(text,val)
Nov 25 Javascript
两种方法实现文本框输入内容提示消失
Mar 17 Javascript
js获取IFRAME当前的URL的方法
Nov 13 Javascript
asp.net刷新本页面的六种方法总结
Jan 07 Javascript
浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
Jan 19 Javascript
jQuery+css3实现转动的正方形效果(附demo源码下载)
Jan 27 Javascript
利用js编写响应式侧边栏
Sep 17 Javascript
最好用的Bootstrap fileinput.js文件上传组件
Dec 12 Javascript
性能优化之代码优化页面加载速度
Mar 01 Javascript
利用PM2部署node.js项目的方法教程
May 10 Javascript
jQuery表单设置值的方法
Jun 30 jQuery
初试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
《一拳超人》埼玉一拳下去,他们存在了800年毫无意义!
2020/03/02 日漫
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
php cli模式学习(PHP命令行模式)
2013/06/03 PHP
php实现扫描二维码根据浏览器类型访问不同下载地址
2014/10/15 PHP
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
PHP两个n位的二进制整数相加问题的解决
2018/08/26 PHP
JS模拟面向对象全解(二、类型与赋值)
2011/07/13 Javascript
使用JavaScript判断图片是否加载完成的三种实现方式
2014/05/04 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
2014/08/08 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
2014/09/24 Javascript
JavaScript调用浏览器打印功能实例分析
2015/07/17 Javascript
js表单提交和submit提交的区别实例分析
2015/12/10 Javascript
js模仿java的Map集合详解
2016/01/06 Javascript
解析javascript瀑布流原理实现图片滚动加载
2016/03/10 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
js弹出窗口返回值的简单实例
2016/05/28 Javascript
jQuery使用animate实现ul列表项相互飘动效果示例
2016/09/16 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
使用taro开发微信小程序遇到的坑总结
2019/04/08 Javascript
在Python的Flask框架中实现单元测试的教程
2015/04/20 Python
python编程实现希尔排序
2017/04/13 Python
python图像常规操作
2017/11/11 Python
python发送多人邮件没有展示收件人问题的解决方法
2019/06/21 Python
pytorch实现线性拟合方式
2020/01/15 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
Python爬虫使用bs4方法实现数据解析
2020/08/25 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
Python实现随机爬山算法
2021/01/29 Python
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2014/01/19 面试题
大学迎新晚会主持词
2014/03/24 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL
SQL Server中锁的用法
2022/05/20 SQL Server