基于admin-template模板请求头带上Token
Posted 捡黄金的少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于admin-template模板请求头带上Token相关的知识,希望对你有一定的参考价值。
实现逻辑如下
1、对于每次请求数据,从cookie中取token并赋值到请求头上(headers.Authorization)
2、对后端返回的数据,如果返回401,则通过存储在cookie中的刷新令牌(refreshTokenKey)来刷新token值,(一般而言token有效期7天或者一天,刷新令牌比token存放的久)
3、如果刷新令牌存在,则通过刷新令牌,重新获取用户信息,包括,token,userInfo(用户信息),refreshToken(刷新令牌)
4、如果刷新令牌不存在,则重新登录
(刷新页面,Vuex状态变成初始值)
发送请求
service.interceptors.request.use(
config =>
// 获取token
const accessToken = PcCookie.get(Key.accessTokenKey)
if (accessToken)
// 如果有token,则通过请求头添加
config.headers.Authorization = `Bearer $accessToken`
// 也可以使用下面这种
// config.headers['Authorization'] = `Bearer $accessToken`
// 后台接收的key:Authorization value值: Bearer $accessToken
return config
,
error =>
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
)
接收后台返回数据
service.interceptors.response.use(
response =>
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000)
//写正常返回逻辑
,
error =>
console.log('err' + error) // for debug
// 判断状态
if (error.response && error.response.status !== 401)
Message(
message: error.message,
type: 'error',
duration: 5 * 1000
)
return Promise.reject(error)
// 如果是401未认证,则通过刷新令牌获取状态信息
let isLock = true//防止重复提交
if (isLock && PcCookie.get(Key.refreshTokenKey))
isLock = false
// 跳转到统一认证终端。实现令牌刷新token的效果
window.location.href = `$process.env.VUE_APP_AUTH_CENTER_URL/refesh?/redirectURL=$window.location.href`
else
// 如果刷新令牌没有,则进入登录页面
window.location.href = `$process.env.VUE_APP_AUTH_CENTER_URL/login?/redirectURL=$window.location.href`
)
以上已经实现请求时候带上token值
Vuex菜单,按钮权限状态管理
vuex 权限菜单集合,根据 vuex 中可访问的菜单,渲染侧边栏组件
创建menu.js
在store下面的module文件夹下面创建menu.js文件如下
// 请求用户权限接口API
import getUserMenuList from "@/api/user"
import PcCookie, Key from '@/utils/cookie'
const state =
init: false,//是否已经加载用户权限
menuList: [],//用户拥有的菜单权限
buttonList: [],//用户拥有的按钮权限
const mutations = //改变状态值
SET_SYSTEM_MENU: (state, data) =>
state.init = true//已经加载用户权限
state.menuList = data.menuTreeList//保存菜单权限
state.buttonList = data.buttonList//保存按钮权限
// 定义行为
const actions =
GetUserMenu( commit )
// reslove正常返回结果,reject异常返回结果
return new Promise((reslove, reject) =>
//获取用户ID
const userId = PcCookie.get(Key.userInfoKey) ? JSON.parse(PcCookie.get(Key.userInfoKey)).uid : null
// 发送请求获取权限信息
if (userId)
getUserMenuList(userId).then(response =>
// 将获取到的菜单按钮数据信息,存放到Vuex进行状态管理
commit('SET_SYSTEM_MENU', response.data)
reslove()
).catch(error =>
// 返回异常对象
reject()
)
)
export default
namespaced: true,//引用需要的模块名称 /menu/GetUserMenu
state,
mutations,
actions
在getters.js中引入state中定义的几个状态,外面使用方式 $store.getters.buttonList
const getters =
........
// 添加菜单相关状态
init: state => state.menu.init,
menuList: state => state.menu.menuList,
buttonList: state => state.menu.buttonList
export default getters
在index,js中引入menu.js给vuex状态管理
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
// tagsView
import tagsView from './modules/tagsView'
//
import menu from './modules/menu'
Vue.use(Vuex)
const store = new Vuex.Store(
modules:
app,
settings,
user,
tagsView,
menu
,
getters
)
export default store
在permission中对,存在token值且没有拿取到菜单,按钮的信息,就调用 store.dispatch('menu/GetUserMenu')方法进行拿取,只要不刷新页面,vuex就会存在菜单按钮信息,通过store.getters.init 判断,就不用每次请求路由都调用(刷新页面置空Vuex数据)
const hasGetUserInfo = PcCookie.get(Key.accessTokenKey)
if (hasGetUserInfo)
// 如果有用户信息,则通过用户ID来查询当前用户的菜单和按钮权限
if (store.getters.init === false)
// 还没有查询用户信息,开始查询用户信息
//因为我们采用namespaced: true,所以需要
store.dispatch('menu/GetUserMenu').then(() =>
//继续访问目标路由,且不会留下history记录
next( ...to, replace: true )
).catch(error =>
Message(
message: "获取用户信息失败",
type: "error"
)
)
else
// 跳转到目标路由
next()
通过Vuex中的管理的数据,动态渲染左边的菜单组件
<sidebar-item v-for="menu in menuList" :key="menu.id" :item="menu" />
import mapGetters from 'vuex'
export default
components: SidebarItem, Logo ,
computed:
...mapGetters([
'sidebar',
'menuList'//获取menuList中的状态值,menuList
]),
<div>
<!-- 没有子菜单,只有一级菜单 -->
<template v-if="!item.children || item.children.length === 0">
<app-link :to="item.url">
<el-menu-item
:index="item.url"
:class=" 'submenu-title-noDropdown': !isNest "
>
<item :icon="item.icon" :title="item.name" />
</el-menu-item>
</app-link>
</template>
<!-- 有子菜单 -->
<el-submenu v-else ref="subMenu" :index="item.id" popper-append-to-body>
<template slot="title">
<item :icon="item.icon" :title="item.name" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.id"
:is-nest="true"
:item="child"
class="nest-menu"
/>
<!-- :base-path="resolvePath(child.path)" -->
</el-submenu>
</div>
以上是关于基于admin-template模板请求头带上Token的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot Feign内部调用时自动带上请求头信息(header)
SpringBoot Feign内部调用时自动带上请求头信息(header)