Vue常见页面(管理+详情+编辑+新增)四、让请求头带上jwt的Authorization
Vue常见页面(管理+详情+编辑+新增)四、让请求头带上jwt的token
如果你们的后端鉴权用的是jwt,一定遇到过这样的接口,是需要带上Authorization的,而且还比较特殊,需要在前面加上一个“bearer ”注意bearer后又一个空格
我尝试了很多种方法,下面三个是我查询出来最靠谱的,但是都没解决我的问题,很困惑,可能是框架的问题吧
链接1
链接2
链接3
接下来我写一下我同事是如何解决的
首先我们先看一下登陆接口
返回了token和token_type,看来bearer是jwt的token的一种类型
定义设置cookie和获取cookie的方法
util/auth.js
这里引入的’js-cookie’是这里的
/Library/Caches/typescript/4.5/node_modules/@types/js-cookie/index"
import Cookies from 'js-cookie'const TokenKey = 'token'export function getToken() { return Cookies.get(TokenKey)}export function setToken(token) { return Cookies.set(TokenKey, token)}export function setCookis(key, value) { return Cookies.set(key, value)}export function removeToken() { return Cookies.remove(TokenKey)}export function getCookis(key) { return Cookies.get(key)}
登陆页面
调用登陆接口的时候将token放到cookie里
handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true console.log("this.$store.dispatch('user/login', this.loginForm)", this.$store.dispatch('user/login', this.loginForm)) this.$store.dispatch('user/login', this.loginForm).then((res) => { console.log('heee' + this.redirect) console.log(res, 'ooo') this.$router.push({ path: this.redirect || '/' }) this.loading = false //通过设置setCookis方法将token放到cookie里 setCookis('token', res.result.token) console.log(getCookis('token')) // getCookis('token') }).catch(() => { this.loading = false }) } else { console.log('登录失败!!') return false } }) }
请求拦截
在封装的request.js里新增请求拦截,我就将整个js文件放在这里了,确实这样就解决了。当然,我也不知道这中方法是不是通用,如果不行,纯当我瞎说,最好还是去用vuex和localStorage吧
import axios from 'axios'import router from '@/router'import { MessageBox, Message} from 'element-ui'import store from '@/store'import { getCookis, getToken} from '@/utils/auth'// create an axios instanceconst service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000, // request timeout headers: { 'Content-Type': 'application/json; charset=utf-8' }})// request interceptorservice.interceptors.request.use( config => { // do something before request is sent //判断是不是能获取到token if (store.getters.token && getToken()) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation config.headers['X-Token'] = getToken() //如果获取到了就在headers里加上Authorization,并且拼接上'bearer ' config.headers['Authorization'] = 'bearer ' + getToken() } return config }, error => { // do something with request error console.log(error) // for debug return Promise.reject(error) })// response interceptorservice.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { Message({ message: res.message || 'Error', type: 'error', duration: 5 * 1000 }) if (res.code === 401) { MessageBox.confirm('登录过期了,请重新登录或取消', '重新登录提示', { confirmButtonText: '重新登陆', cancelButtonText: '取消', type: 'warning' }).then(() => { router.push('/login') }) } return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { if (error.message !== 'timeout of 5000ms exceeded') { if (error.response.data.code === 403) { MessageBox.confirm('登录过期了,请重新登录或取消', '重新登录提示', { confirmButtonText: '重新登陆', cancelButtonText: '取消', type: 'warning' }).then(() => { router.push('/login') }) } else if (error.response.code === 422) { Message({ message: '前端bug,请求接口缺少参数,请复制request > payload > source中的内容联系【客户端】作者', type: 'error', duration: 10 * 1000 }) } else if (error.response.code === 500) { Message({ message: '服务端bug,请求接口缺少参数,请复制request > payload > source中的内容联系【服务端】作者', type: 'error', duration: 10 * 1000 }) } else if (error.response.status === 406) { Message({ message: error.response.data.message, type: 'error', duration: 10 * 1000 }) } else { Message({ message: error, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } } else { console.log(2) Message({ message: '连接超时,请检查网络和VPN!', type: 'error', duration: 5 * 1000 }) } })export default service