vue、axios请求头自定义

前言

由于业务性质缘由,以前的项目,其实没有作帐号管理,默认登陆。
最近要求作帐号权限管理,因此须要在api请求中验证token。前端

前端逻辑

  • 登陆的时候后端返回一个token。
  • 登录成功,token写入sessionStorage/localStorage。
  • vuex存储token。
  • axios拦截请求,请求头判断token是否存在,若是存在,设置自定义字段config.headers.Token = token
  • axios拦截响应,获取HTTP状态,若是状态为401,即未登陆/登录过时,状况本地相关token信息,跳转到登陆页。
  • 其余设置Content-Type、数据格式化
  • 跨域相关设置withCredentialscrossDomain

后端逻辑

  • 设置支持自定义字段token。
  • Access-Control-Allow-Headers:x-requested-with,content-type,token
  • 拦截OPTIONS请求,返回200。若是跨域,须要设置跨域容许,不然前端不能正确获得OPTIONS结果。
  • 对于GET/POST请求,检测请求头中的token字段,校验结果决定是否走下一步流程。
  • 若是校验经过,走正常的业务逻辑。不然,设置HTTP状态为401,中断业务流程,返回校验结果。

问题

解决过程当中,容易出现如下问题:vue

  • 前端拦截请求的时候,设置自定义字段,首字母大小写。必须大写
  • 后端处理OPTIONS请求的时候,不能正确设置容许跨域,致使前端不能正确获得OPTIONS请求结果,GET/POST请求没有发出。

结语

问题老是解决不完的,每解决完一个问题,都是一次收获!
附上前端js代码:ios

//设置post的默认格式为form-data
//请求拦截:若是存在token,则把token带在请求头上发送出去
axios.defaults.withCredentials = true;
axios.defaults.crossDomain = true;
axios.interceptors.request.use((config) => {
    config.headers = {'Content-Type':'application/x-www-form-urlencoded'}
    let token = store.state.token;
    if (token) {
        config.headers.Token = token;
    }
    config.data = qs.stringify(config.data, {arrayFormat: 'brackets'});
    return config;
});
//响应拦截:若是htpp状态401,则是须要登陆,清除token,跳转到登陆页
axios.interceptors.response.use(res =>{
    return res
}, error => {
    if(error.response && error.response.status === 401){
        store.commit('clearToken')
        router.replace({
            path: '/login',
        })
    }
    return Promise.reject(error.response ? error.response.data : error)
})