浏览代码

axios请求token逻辑更新

Michael Wang 6 年之前
父节点
当前提交
1ac4267e74
共有 4 个文件被更改,包括 178 次插入28 次删除
  1. 30 0
      src/auth/auth.js
  2. 2 1
      src/main.js
  3. 23 27
      src/plugins/axiosApp.js
  4. 123 0
      src/plugins/axiosCommonService.js

+ 30 - 0
src/auth/auth.js

@@ -0,0 +1,30 @@
+import Cookies from "js-cookie";
+
+// const TokenKey = "Admin-Token";
+
+// export function getToken() {
+//   return Cookies.get(TokenKey);
+// }
+
+// export function setToken(token) {
+//   return Cookies.set(TokenKey, token);
+// }
+
+// export function removeToken() {
+//   return Cookies.remove(TokenKey);
+// }
+
+const Key = "key";
+const Token = "token";
+
+export function getKeyToken() {
+  return [Cookies.get(Key), Cookies.get(Token)];
+}
+
+export function setKeyToken({ key, token }) {
+  return Cookies.set(Key, key) && Cookies.set(Token, token);
+}
+
+export function removeKeyToken() {
+  return Cookies.remove(Key) && Cookies.remove(Token);
+}

+ 2 - 1
src/main.js

@@ -3,7 +3,8 @@ import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 // import "./registerServiceWorker";
-import "./plugins/axios";
+import "./plugins/axiosCommonService";
+import "./plugins/axiosApp";
 import "./plugins/iview";
 
 Vue.config.productionTip = false;

+ 23 - 27
src/plugins/axios.js → src/plugins/axiosApp.js

@@ -1,6 +1,7 @@
 import Vue from "vue";
 import axios from "axios";
 import router from "../router";
+import { getKeyToken, removeKeyToken } from "../auth/auth";
 
 // Full config:  https://github.com/axios/axios#request-config
 // axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
@@ -13,32 +14,25 @@ let config = {
   withCredentials: true // Check cross-site Access-Control
 };
 
-const _axios = axios.create(config);
+const _axiosApp = axios.create(config);
 
 /**
- * A. token lifecycle
- * 1. /login UI => localStorage.removeItem('token') && localStorage.setItem('token')
- * 2. non /login UI => axios if(!wk_token) wk_token = window.sessionStorage.getItem("token"), send request
- * 3. if axios request fail with 401/403, wk_token = null, redirect to /login removeItem('token')
- * 4. logout to /login, before send request, invalidate wk_token
- * */
+ * B. new token lifecycle
+ * 1. 任何接口地址都尝试加上 key & token (第三方请求,单独做新的$http)
+ * 2. 如果没有 key & token,就当做这是无需认证的api
+ * 3. 做好token失效的处理,在interceptors.response 统一删除
+ * 4. key & token 由外部管理,不在此插件管理。一般是在登录成功后设置。
+ * xx. 额外:通过js-cookie将key等存入cookie
+ */
 
-let wk_token, wk_key;
-
-_axios.interceptors.request.use(
+_axiosApp.interceptors.request.use(
   function(config) {
-    // Do something before request is sent
     if (config.url.includes("/login") === false) {
-      if (!wk_token) {
-        wk_token = window.sessionStorage.getItem("token");
-        wk_key = window.sessionStorage.getItem("key");
-      }
-      if (wk_token && config.headers.common["token"] == null) {
+      let [wk_token, wk_key] = getKeyToken();
+      if (wk_token) {
         config.headers.common["token"] = wk_token;
         config.headers.common["key"] = wk_key;
       }
-    } else {
-      wk_token = null;
     }
     return config;
   },
@@ -54,7 +48,7 @@ _axios.interceptors.request.use(
 );
 
 // Add a response interceptor
-_axios.interceptors.response.use(
+_axiosApp.interceptors.response.use(
   response => {
     return response;
   },
@@ -77,16 +71,16 @@ _axios.interceptors.response.use(
       Vue.prototype.$alert("登录失效,请重新登录!", "提示", {
         confirmButtonText: "确定",
         callback: () => {
-          router.push("/login/" + localStorage.getItem("domain"));
+          removeKeyToken();
+          router.push("/login/");
         }
       });
       return Promise.reject(error);
     } else if (status == 405) {
-      Vue.prototype.$alert("没有权限!", "提示", {
-        confirmButtonText: "确定",
-        callback: () => {
-          router.push("/login/" + localStorage.getItem("domain"));
-        }
+      Vue.prototype.$notify({
+        showClose: true,
+        message: "没有权限!",
+        type: "error"
       });
       return Promise.reject(error);
     }
@@ -112,11 +106,11 @@ _axios.interceptors.response.use(
 );
 
 Plugin.install = function(Vue) {
-  Vue.$http = _axios;
+  Vue.$http = _axiosApp;
   Object.defineProperties(Vue.prototype, {
     $http: {
       get() {
-        return _axios;
+        return _axiosApp;
       }
     }
   });
@@ -125,3 +119,5 @@ Plugin.install = function(Vue) {
 Vue.use(Plugin);
 
 export default Plugin;
+
+export const httpApp = _axiosApp;

+ 123 - 0
src/plugins/axiosCommonService.js

@@ -0,0 +1,123 @@
+import Vue from "vue";
+import axios from "axios";
+import router from "../router";
+import { getKeyToken, removeKeyToken } from "../auth/auth";
+
+// Full config:  https://github.com/axios/axios#request-config
+// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
+// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
+// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+
+let config = {
+  // baseURL: process.env.baseURL || process.env.apiUrl || ""
+  timeout: 60 * 1000, // Timeout
+  withCredentials: true // Check cross-site Access-Control
+};
+
+const _axiosCommonService = axios.create(config);
+
+/**
+ * B. new token lifecycle
+ * 1. 任何接口地址都尝试加上 key & token (第三方请求,单独做新的$http)
+ * 2. 如果没有 key & token,就当做这是无需认证的api
+ * 3. 做好token失效的处理,在interceptors.response 统一删除
+ * 4. key & token 由外部管理,不在此插件管理。一般是在登录成功后设置。
+ * xx. 额外:通过js-cookie将key等存入cookie
+ */
+
+_axiosCommonService.interceptors.request.use(
+  function(config) {
+    if (config.url.includes("/login") === false) {
+      let [wk_token, wk_key] = getKeyToken();
+      if (wk_token) {
+        config.headers.common["token"] = wk_token;
+        config.headers.common["key"] = wk_key;
+      }
+    }
+    return config;
+  },
+  function(error) {
+    // Do something with request error
+    Vue.prototype.$notify({
+      showClose: true,
+      message: error,
+      type: "error"
+    });
+    return Promise.reject(error);
+  }
+);
+
+// Add a response interceptor
+_axiosCommonService.interceptors.response.use(
+  response => {
+    return response;
+  },
+  error => {
+    if (!error.response) {
+      // "Network Error" 网络不通,直接返回
+
+      Vue.prototype.$notify({
+        showClose: true,
+        message: "网络连接异常,请检查网络设置。",
+        type: "error"
+      });
+      return Promise.reject(error);
+    }
+    // 这里是返回状态码不为200时候的错误处理
+    let status = error.response.status;
+
+    // 登录失效 跳转登录页面
+    if (status == 403 || status == 401) {
+      Vue.prototype.$alert("登录失效,请重新登录!", "提示", {
+        confirmButtonText: "确定",
+        callback: () => {
+          removeKeyToken();
+          router.push("/login/");
+        }
+      });
+      return Promise.reject(error);
+    } else if (status == 405) {
+      Vue.prototype.$notify({
+        showClose: true,
+        message: "没有权限!",
+        type: "error"
+      });
+      return Promise.reject(error);
+    }
+
+    if (status != 200) {
+      const data = error.response.data;
+      if (data && data.desc) {
+        Vue.prototype.$notify({
+          showClose: true,
+          message: data.desc,
+          type: "error"
+        });
+      } else {
+        Vue.prototype.$notify({
+          showClose: true,
+          message: "未定义异常: " + JSON.stringify(data, 2),
+          type: "error"
+        });
+      }
+      return Promise.reject(error);
+    }
+  }
+);
+
+Plugin.install = function(Vue) {
+  Vue.$httpCommonService = _axiosCommonService;
+  Object.defineProperties(Vue.prototype, {
+    $httpCommonService: {
+      get() {
+        return _axiosCommonService;
+      }
+    }
+  });
+};
+
+Vue.use(Plugin);
+
+export default Plugin;
+
+export const httpCommonService = _axiosCommonService;