(一)实现一个完整的前后端请求登录的过程前端逻辑(axios+process+Vue-ls+Antd的notification)

1:配置自适应(开发,生产)环境的全局变量

在根目录下面创建两个文件.env.development ,.env.production

(1).env.development 开发环境

NODE_ENV=development
VUE_APP_AXIOS_BASEURL=http://localhost:43597/
VUE_APP_AXIOS_API=/api

(2).env.production 生产环境

NODE_ENV=production
VUE_APP_AXIOS_BASEURL=http://xxxx:43597/
VUE_APP_AXIOS_API=/api

2.1:安装ant design vue,引用notification,权限验证失败后打印对应的错误信息

import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
app.use(Antd)
2.2:定义异常方法,在axiosrequest.js里面,然后引用notification
import notification from 'ant-design-vue/es/notification'
const err = (error) => {
  if (error.response) {
    const data = error.response.data
    if (error.response.status === 403) {
       notification.error({
        message: 'Forbidden',
        description: data.message
       })
       return
    }
    if (error.response.status === 401) {
      notification.error({
        message: '授权失败1',
        description: '没有权限访问该功能2'
      })
      return
    }
 
  }
  return Promise.reject(error)
}
后端返回通常是终结点,表示请求异常

public void OnAuthorization(AuthorizationFilterContext context)
{

//context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "pms_exp");
//context.HttpContext.Response.Headers.Add("pms_exp", "1");
context.Result = new ContentResult()
{
Content = new { result = "denied", status = false, code = (int)HttpStatusCode.Unauthorized, message = "没有传入token" }.Serialize(),
ContentType = "application/json",
//StatusCode = (int)HttpStatusCode.Unauthorized,
StatusCode = (int)HttpStatusCode.Forbidden
};
}

2.3:二次封装axios组件(axiosrequest.js),避免在main.js里面写大量js方法,install(Vue)里面的vue就是在main.js里面里的Vue,把main里面Vue的操作传到install(Vue)里面去,避免了在main.js里面去写方法

import Axios from "axios";
Axios.defaults.timeout = 100000//设置超时时间
Axios.defaults.baseURL = process.env.VUE_APP_AXIOS_BASEURL+ process.env.VUE_APP_AXIOS_API //设置axios的baseUrl
Axios.defaults.withCredentials = true //允许跨域携带cookie信息
export default{
  Axios,
  install(Vue){
   
    Axios.interceptors.request.use(
      config => {
        var token=Vue.ls.get('Access-Token');//登陆成功后把token存到Vue.ls里面app.ls.set('Access-Token','wert333')
        if(token){//如果token有值就把token带到header里面去请求后端接口
        config.headers.Authorization =token;
        }
          return config;
      }, err)//就是上面2.2定义的err

      Axios.interceptors.response.use((response) => {
         //context.HttpContext.Response.Headers.Add("pms_exp", "1");后端token要过期的适合就给呢里一个标记,标识要过期了,该刷新token了
        //注意:后端一定要 context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "pms_exp");否则呢里是取不到的,cores里面的跨域对这里没有作用
        if(response.headers['pms_exp']=='1'){//或者response.headers.pms_exp,表是token已经快要过期了,需要刷新token了
          //alert(response.headers.pms_exp);
          refreshToken (response) //提交后台刷新token
        }
         //return Promise.resolve(response);  
        return response
       }, err)//就是上面2.2定义的err
    Object.defineProperty(Vue.config.globalProperties, '$rootUrl', { value: process.env.VUE_APP_AXIOS_BASEURL+ process.env.VUE_APP_AXIOS_API })//定义全局变量$rootUrl,其他地方可以通过this.$rootUrl获取
  }
}

3:二次封装vue-ls(vueis.js),避免在main.js里面写大量js方法,install(Vue)里面的vue就是在main.js里面里的Vue,把main里面Vue的操作传到install(Vue)里面去,避免了在main.js里面去写方法
import Storage from 'vue-ls';
const options = {
  namespace: 'vuejs__', // key键前缀
  name: 'ls', // 命名Vue变量.[ls]或this.[$ls],
  storage: 'local', // 存储名称: session, local, memory
};
  export default{
    install(Vue){
      Vue.use(Storage, options);//呢个Vue就是main.js传过来的vue
    }
  }
4:在main.js引用上面定义的两个js
 import AxiosObj from  './axiosrequest.js'
 import vueis from "./vueis.js"
 //挂载上面的两个js
app.use(vueis)
app.use(AxiosObj)
5:将app.ls,Axios放到全局变量里面,方便其他页面通过this.的方式获取,app.ls.set('Access-Token','')模仿登陆成功后返回的token,把token存到app.ls缓存里面

app.ls.set('Access-Token','wert333')//假如wert333就是后端登录成功后返回的token

app.config.globalProperties.appls=app.ls;//

main引用的js里面不能直接用this.appIs获取,只能通过install传参使用(Vue.ls.get('')),其他地方可以使用this.appI
app.config.globalProperties.$Http = AxiosObj.Axios//通过this.$Http来取Axios对象
6:刷新token的方法
function refreshToken (response) {
  return service.post('/Sys_User/replaceToken').then(res => {
    if (res.status) {//如果返回成功
      Vue.ls.set(ACCESS_TOKEN, 'Bearer ' + res.data, 7 * 24 * 60 * 60 * 1000)//重新设置缓存的token值
    } else {
                //如果token已经失效了,调用退出登录的接口,刷新页面
                setTimeout(() => {
                  window.location.reload()
                }, 1500)
          
    }
  })
}

 

 

注意:后端一定要 context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "pms_exp");否则response.headers['pms_exp']是取不到的,cores里面的跨域对response.headers['pms_exp']是没有作用的

response.headers['pms_exp']取后端的pms_exp值

 

 

 
  //return Promise.resolve(response);  
        return response
posted @   yingxianqi  阅读(559)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示