Browse Source

imporve login process

Michael Wang 5 years ago
parent
commit
c77a7f548d

+ 7 - 24
src/auth/auth.js

@@ -1,32 +1,15 @@
 import Cookies from "js-cookie";
 
-// const TokenKey = "Admin-Token";
+const TokenKey = "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 getToken() {
+  return Cookies.get(TokenKey);
 }
 
-export function setKeyToken({ uid, token }) {
-  Cookies.set(Key, uid);
-  Cookies.set(Token, token);
+export function setToken(token) {
+  return Cookies.set(TokenKey, token);
 }
 
-export function removeKeyToken() {
-  Cookies.remove(Key);
-  Cookies.remove(Token);
+export function removeToken() {
+  return Cookies.remove(TokenKey);
 }

+ 3 - 0
src/main.js

@@ -1,9 +1,11 @@
 import Vue from "vue";
+// 4KB non-zip
 import Navigation from "vue-navigation";
 import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 // import "./registerServiceWorker";
+// 27KB non-zip
 import "./plugins/axiosIndex";
 import "./plugins/customComponents";
 import "./filters";
@@ -13,6 +15,7 @@ import "./plugins/vueAwesome";
 import "./plugins/helpers";
 
 // styles begin
+// bootstrap 133KB non-zip
 import "./styles/bootstrap.scss";
 import "./styles/global.css";
 // styles end

+ 2 - 2
src/mixins/logout.js

@@ -1,10 +1,10 @@
-import { removeKeyToken } from "@/auth/auth";
+import { removeToken } from "@/auth/auth";
 import Vue from "vue";
 
 Vue.mixin({
   methods: {
     logout(cause = "") {
-      removeKeyToken();
+      removeToken();
       // window._hmt.push(["_trackEvent", "退出", cause]);
       this.$router.push("/login" + cause);
     },

+ 29 - 27
src/plugins/axiosApp.js

@@ -1,8 +1,12 @@
 import Vue from "vue";
+import Store from "@/store";
 import axios from "axios";
 import { loadProgressBar } from "axios-progress-bar";
 import cachingGet from "./axiosCache";
-import { getKeyToken, removeKeyToken } from "../auth/auth";
+import { notifyInvalidTokenThrottled } from "./axiosNotice";
+import { getToken, removeToken } from "../auth/auth";
+
+const PLATFORM = "Wap";
 
 // Full config:  https://github.com/axios/axios#request-config
 // axios.defaults.baseURL = process.env.BASE_URL || process.env.apiUrl || '';
@@ -17,23 +21,31 @@ const cacheGetUrls = [];
 
 const _axiosApp = 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
- */
+function gToken(uri, token) {
+  const now = Date.now();
+  // console.log(`${uri}&${now}&${token}`);
+  const a = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  let randomStr = "";
+  for (let i = 0; i < 6; i++) {
+    const idx = Math.round(Math.random() * 100) % a.length;
+    randomStr += a[idx];
+  }
+
+  const Authorization = `Token ${randomStr}${btoa(
+    uri + "&" + now + "&" + token
+  )}`;
+
+  return Authorization;
+}
 
 _axiosApp.interceptors.request.use(
   function(config) {
-    if (config.url.endsWith("Login") === false) {
-      const [wk_token, wk_key] = getKeyToken();
-      if (wk_token) {
-        config.headers.common["token"] = wk_token;
-        config.headers.common["key"] = wk_key;
-      }
+    const wk_token = getToken();
+    if (wk_token) {
+      config.headers.common["Authorization"] = gToken(config.url, wk_token);
+      config.headers.common["deviceId"] = Store.state.user.deviceId;
+      config.headers.common["domain"] = Store.state.user.domain;
+      config.headers.common["platform"] = PLATFORM;
     }
     return config;
   },
@@ -69,18 +81,8 @@ _axiosApp.interceptors.response.use(
 
     // 登录失效 跳转登录页面
     if (status == 403 || status == 401) {
-      if (
-        window.___lastInvalidDate === undefined ||
-        window.___lastInvalidDate < Date.now() - 300
-      ) {
-        Vue.prototype.$notify({
-          showClose: true,
-          message: "登录失效,请重新登录!",
-          type: "error",
-        });
-        window.___lastInvalidDate = Date.now();
-      }
-      removeKeyToken();
+      notifyInvalidTokenThrottled();
+      removeToken();
       return Promise.reject(error);
     } else if (status == 405) {
       Vue.prototype.$notify({

+ 11 - 0
src/plugins/axiosNotice.js

@@ -0,0 +1,11 @@
+import Vue from "vue";
+import throttle from "lodash-es/throttle";
+
+// function printErr(val) {
+export const notifyInvalidTokenThrottled = throttle(() => {
+  Vue.prototype.$notify({
+    showClose: true,
+    message: "登录失效,请重新登录!",
+    type: "error",
+  });
+}, 1000);

+ 21 - 10
src/router/index.js

@@ -1,4 +1,4 @@
-import { getKeyToken } from "@/auth/auth";
+import { getToken } from "@/auth/auth";
 import { isNil } from "lodash-es";
 import Vue from "vue";
 import Router from "vue-router";
@@ -55,19 +55,30 @@ let router = new Router({
     //     return propsValidator(route, XXX);
     //   }
     // }
+    // {
+    //   path: "/login",
+    //   component: () =>
+    //     import(/* webpackChunkName: "login" */ "../features/Login/Login.vue"),
+    // },
+    {
+      path: "/*",
+      component: () =>
+        import(/* webpackChunkName: "default" */ "../views/404.vue"),
+    },
   ],
 });
 
+// FIXME: router.route 添加 auth,代表是否需要认证。
+// FIXME: roles. 根据roles来授权。
+// FIXME: 在Login页面,验证通过后,返回redirectTo 页面。
 router.beforeEach((to, from, next) => {
-  const [uid, token] = getKeyToken();
-  if ((isNil(uid) || isNil(token)) && to.path.includes("/login") === false) {
-    if (
-      window.___lastInvalidDate === undefined ||
-      window.___lastInvalidDate < Date.now() - 300
-    ) {
-      window.___lastInvalidDate = Date.now();
-    }
-    router.push("/login");
+  if (to.path) {
+    window._hmt.push(["_trackPageview", to.fullPath]);
+  }
+
+  const token = getToken();
+  if (isNil(token) && to.path.includes("/login") === false) {
+    router.push("/login?redirectTo=" + encodeURI(to.fullPath));
     next(false);
   } else {
     next();

+ 5 - 5
src/store/modules/user.js

@@ -1,5 +1,5 @@
 import { loginByUsername, loginByPhone, sendSMS, logout } from "@/api/login";
-import { removeKeyToken, setKeyToken } from "@/auth/auth";
+// import { removeKeyToken, setKeyToken } from "@/auth/auth";
 import { omit } from "lodash-es";
 import { LOGIN_BY_USERNAME, LOGIN_BY_PHONE, SEND_SMS } from "../action-types";
 
@@ -33,14 +33,14 @@ const user = {
       return loginByUsername(userInfo).then(response => {
         const data = response.data;
         commit("SET_USER", omit(data.accessAdminUser, ["token", "uid"]));
-        setKeyToken(response.data.accessAdminUser);
+        // setKeyToken(response.data.accessAdminUser);
       });
     },
     [LOGIN_BY_PHONE]({ commit }, userInfo) {
       return loginByPhone(userInfo).then(response => {
         const data = response.data;
         commit("SET_USER", omit(data.accessAdminUser, ["token", "uid"]));
-        setKeyToken(response.data.accessAdminUser);
+        // setKeyToken(response.data.accessAdminUser);
       });
     },
     [SEND_SMS]({ commit }, userInfo) {
@@ -55,7 +55,7 @@ const user = {
         logout(state.token)
           .then(() => {
             commit("SET_USER", null);
-            removeKeyToken();
+            // removeKeyToken();
             resolve();
           })
           .catch(error => {
@@ -68,7 +68,7 @@ const user = {
     FedLogOut({ commit }) {
       return new Promise(resolve => {
         commit("SET_USER", null);
-        removeKeyToken();
+        // removeKeyToken();
         resolve();
       });
     },

+ 5 - 0
src/views/401.vue

@@ -0,0 +1,5 @@
+<template>
+  <h3>
+    没有权限查看!
+  </h3>
+</template>

+ 5 - 0
src/views/404.vue

@@ -0,0 +1,5 @@
+<template>
+  <h3>
+    页面找不到!
+  </h3>
+</template>