许多页面在访问之前是需要登陆验证的,如果用户没有登录,则需要用户跳转到登陆页面进行登录。
结合自身练习以及资料进行整理,提供以下几种方式

一、Vue通过router实现登录拦截

1.requireAuth

requireAuth属性作用是表明该路由是否需要登陆验证,在进行全局拦截时,通过该属性进行判断,该属性包含在meta属性中。

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

routes=[
	{
		path:'/',
		name:'Default',
		redirect:'/home',
		component:Home,
		meta:{
			requireAuth:true //此时表示进入这个路由是需要登录的
		}
	},
	{
		name:'login',
		path:'/login'
	}
]

2.router.beforeEach

beforeEach时router的钩子函数,该函数在进入每个网页之前调用,该函数接收三个参数:
①from:即将离开的路由
②to:即将要跳转的路由
③next:跳转方法,在beforeEach函数中作为结束语句调用,以实现页面跳转。
next(false):中断当前的导航。如果浏览器的url改变了(可能是手动或浏览器按钮后退),那么url地址会重置到from路由对应的地址。
next(’/’)或者next({path:’/’}):跳转到一个不同的地址。当前导航被中断,然后进行一个新的导航。

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

router.beforeEach((from,to,next)=>{
	if(to.meta.requireAuth){//判断跳转的路由是否需要登录,如果前端没有登录信息则直接拦截,如果有则判断后端是否正常登录(防止构造参数绕过)
		if(store.state.token){//vuex.state判断token是否存在 即是否有用户登录
			next()//已登录进行跳转
		}}else{
			next({
				path:'/login',
				query:{redirect:to.fullPath}//将跳转的路由path作为参数,登陆成功后跳转到该路由,这里的to.fullPath是带的一个参数传给登陆页面,登录之后要跳转的路由
			})
		}
	}else{
		next()
	}
}

登陆完成后,在登陆中改变vuex的状态

	login () {
        var _this = this
        this.$axios.post('/login', {
          username: this.loginForm.username,
          password: this.loginForm.password
        }).then(resp => {
          if (resp.data.code === 200) {
            var data = resp.data
            _this.$store.commit('login', data)
            var path = _this.$route.query.redirect
            _this.$router.replace({path: path === '/' || path === undefined ? '/admin/dashboard' : path})
          } else {
            this.$alert(resp.data.data, '提示', {
              confirmButtonText: '确定'
            })
          }
        }).catch(failResponse => {
        })
      }

二、拦截器(通过使用axios拦截器)

如果要统一处理所有的http请求和响应,就需要使用axios的拦截器。通过配置http response inteceptor,当后端接口返回错误信息,让用户重新登陆

// 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) {
      store.commit('logout')
      router.replace('/login')
    }
    // 返回接口返回的错误信息
    return Promise.reject(error)
  })

三、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
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐