【Vue+axios】 登录拦截验证token,路由拦截器
GitHub项目地址:https://github.com/superman66/vue-axios-github/tree/master/src
router文件夹中的index.js添加路由权限校验
meta: { requireAuth: true, },
页面刷新时,重新赋值token
if (window.localStorage.getItem('token')) {
store.commit(types.LOGIN, window.localStorage.getItem('token'))
}
在路由配置的最后,我们要利用vue-router提供的钩子函数beforeEach()对路由进行判断
router.beforeEach((to, from, next) => {
if (to.matched.some(r => r.meta.requireAuth)) {
if (store.state.token) {
next();
}
else {
next({
name: 'login',
param: {redirect: to.fullPath}
})
}
}
else {
next();
}
})
export default router;
每个钩子方法接收三个参数:
* to: Route: 即将要进入的目标 路由对象
* from: Route: 当前导航正要离开的路由
* next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
* next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
* next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
* next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
确保要调用 next 方法,否则钩子就不会被 resolved。
在router文件夹中新建http.js,js中主要是统一处理http的请求和响应。通过配置http response inteceptor
,当后端接口返回401 Unauthorized(未授权)
,让用户重新登录。
import axios from 'axios'
import store from './../store/store'
import * as types from './../store/types'
import router from './index'
// axios 配置
axios.defaults.timeout = 5000;
// http request 拦截器
axios.interceptors.request.use(
config => {
if (store.state.token) {
config.headers.Authorization = `Bearer ${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({
name: 'HelloWorld',
param: {redirect: router.currentRoute.fullPath}
})
}
}
// console.log(JSON.stringify(error));//console : Error: Request failed with status code 402
return Promise.reject(error.response.data)
});
export default axios;
通过上面这两步,就可以在前端实现登录拦截了。登出
功能也就很简单,只需要把当前token清除,再跳转到首页即可。
由于项目中我们使用了vuex,所以我们需要新建一个store文件夹,它是vuex的状态管理文件夹。
每一个 Vuex 应用的核心就是 store(仓库)。"store" 基本上就是一个容器,它包含着你的应用中大部分的状态(state)。Vuex 和单纯的全局对象有以下两点不同:
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
创建 store
的过程很简单,只需要提供一些初始 state
对象和一些 mutations
:
store.js
import Vuex from 'vuex'
import Vue from 'vue'
import * as types from './types'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {},
token: null,
title: ''
},
mutations: {
[types.LOGIN]: (state, data) => {
localStorage.token = data;
state.token = data;
},
[types.LOGOUT]: (state) => {
localStorage.removeItem('token');
state.token = null
},
[types.TITLE]: (state, data) => {
state.title = data;
}
}
})
types.js
export const LOGIN = 'login';
export const LOGOUT = 'logout';
export const TITLE = 'title'
Vuex 主要有几个核心概念:
- State: 状态,也就是数据来源,可以看作是组件中的
data
,不过是抽离的公共数据。 - Getters:可以理解为 store 的计算属性。
- Mutations:更改 store 中的 state 的方法,类似于事件,每个 mutation 都有一个字符串的
事件类型 (类似于事件的名称)
和一个回调函数 (handler)
,这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。 mutation 必须是同步函数。 - Actions:Action 类似于 mutation,不过 Action 提交的是 mutation ,而不是直接变更状态,并且 Action 可以包含任何异步操作。
- Modules:Vuex 允许我们将 store 分割成模块,避免当状态较多时, store 对象过于臃肿。
更多关于vuex请查看官方文档
在main.js中需要添加axios、store
new Vue({
el: '#app',
axios,
router,
store,
components: { App },
template: '<App/>'
})
更多推荐
所有评论(0)