Vue封装路由跳转方法,vue-router对query传参进行加密解密

1.引入库crypto-js

npm install crypto-js

2.封装加密、解密方法crypto.js文件,根据自己开发习惯,放在工具类utils文件夹即可(直接复制)

const CryptoJS = require("crypto-js"); //引用AES源码js

const key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF"); //十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse("ABCDEF1234123412"); //十六位十六进制数作为密钥偏移量

//加密方法
function Encrypt(word) {
  let srcs = CryptoJS.enc.Utf8.parse(word);
  let encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  return encrypted.ciphertext.toString().toUpperCase();
}

//解密方法
function Decrypt(word) {
  let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
  let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  let decrypt = CryptoJS.AES.decrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}

const desKey = CryptoJS.enc.Utf8.parse("1");

//DES加密方法
function desEncrypt(message) {
  let encrypted = CryptoJS.DES.encrypt(message, desKey, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  });
  return encrypted.toString();
}
//DES解密方法
function desDecrypt(ciphertext) {
  if (ciphertext === "" || ciphertext === null || ciphertext === undefined) {
    return "";
  }
  if (typeof ciphertext != "string") {
    ciphertext = ciphertext.toString();
  }
  //为解决返回url自动把加密转义
  ciphertext = ciphertext.replace(/%2F/g, "/");
  ciphertext = ciphertext.replace(/%20/g, "+");
  ciphertext = ciphertext.replace(/ /g, "+");
  ciphertext = ciphertext.replace(/%3D/g, "=");
  var decrypted = CryptoJS.DES.decrypt(
    {
      ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
    },
    desKey,
    {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    }
  );
  return decrypted.toString(CryptoJS.enc.Utf8);
}

export default {
  Encrypt,
  Decrypt,
  desEncrypt,
  desDecrypt
};

3.引入到router文件里并使用。(不要直接复制,里面有我自己的代码)

注:注意标注的地方才是加密解密相关代码

import Vue from "vue";
import Router from "vue-router";
import commonRouter from "./modules/common"; // 公共路由
import shoppingRouter from "./modules/shopping"; // 首页路由
import loginRouter from "./modules/login"; // 登录路由
Vue.use(Router);

// 加密解密开始
import crypto from "../utils/crypto"; // 引入
function deepCopy(obj) {
  if (obj instanceof Object) {
    const newObj = {};
    if (Array.isArray(obj)) {
      const arr = [];
      obj.forEach(item => {
        arr.push(deepCopy(item));
      });
      return arr;
    } else {
      for (const key in obj) {
        const value = obj[key];
        if (typeof value === "function") {
          newObj[key] = value.bind(newObj);
        } else if (typeof value === "object") {
          if (Array.isArray(value)) {
            newObj[key] = [];
            value.forEach(item => {
              newObj[key].push(deepCopy(item));
            });
          } else {
            newObj[key] = deepCopy(value);
          }
        } else {
          newObj[key] = value;
        }
      }
    }
    return newObj;
  } else {
    return obj;
  }
}

const originalPush = Router.prototype.push;
Router.prototype.push = function push(location, onResolve, onReject) {
  if (onResolve || onReject)
    return originalPush.call(this, location, onResolve, onReject);
  // 解决空对象中含有{__ob__: Observer},深拷贝
  let newLocation = deepCopy(location);
  // let newLocation = location
  if (newLocation?.query && Object.keys(newLocation.query).length !== 0) {
    newLocation = location.query?.__params
      ? location
      : {
          ...location,
          query: {
            __params: crypto.Encrypt(JSON.stringify(newLocation.query))
          }
        };
  }
  return originalPush.call(this, newLocation);
};

const originalRoe = Router.prototype.resolve;
Router.prototype.resolve = function resolve(location, onResolve, onReject) {
  if (onResolve || onReject)
    return originalRoe.call(this, location, onResolve, onReject);
  // 解决空对象中含有{__ob__: Observer},深拷贝
  let newLocation = deepCopy(location);
  // let newLocation = location
  if (newLocation?.query && Object.keys(newLocation.query).length !== 0) {
    newLocation = location.query?.__params
      ? location
      : {
          ...location,
          query: {
            __params: crypto.Encrypt(JSON.stringify(newLocation.query))
          }
        };
  }
  return originalRoe.call(this, newLocation);
};
// 加密解密结束


export const constantRouterMap = [
  ...commonRouter,
  ...shoppingRouter,
  ...loginRouter,
  {
    path:
      "/eGK7KbU4gs8xA4Uy-4NH42ten01820HFBXB5XoHwkUVKTsgfWTz6FmpkR0gO9ESR8wd-&eaid-b32aa700081C4C00000564C26251",
    component: () => import("@/app/shop/views/list.vue"),
    name: "list"
  }
];

export default new Router({
  mode: "history", // require service support
  // 浏览器回退,切换路由时默认滚动的位置
  scrollBehavior: () => ({
    y: 0
  }),
  routes: constantRouterMap
});

4.main.js全局引入,注入原型prototype。

import crypto from "@/basa/utils/crypto";
Vue.prototype.$crypto = crypto;

5.主页通过watch监听路由并解密参数,一般是App.vue或者Layout.vue,也就是app-main标签放置的页面

<template>
  <div>
    <div class="ccui-app-wrapper">
      <div class="ccui-main-container">
        <!-- 应用导航 -->
        <!--<el-top-nav-menu-3
          ref="topNavMenu"
          :subMenu="menu"
          :appTitle="appTitle"
          :companyTitle="companyTitle"
          dashboard=""
          class="no-print"
          @onSubmitSkip="onJump"
          @ccuiHelp="appHelp"
          :logo="orgLogo"
        >
        </el-top-nav-menu-3>-->

        <!-- 内容区 -->
        <app-main
          class=""
          style="min-height: auto; margin-left: 0;line-break: anywhere;"
        />
      </div>
    </div>
  </div>
</template>

<script>
import Vue from "vue";

watch: {
    $route(to, from) {
      this.setMenuInit();
    },
    "$route.query": {
      immediate: true,
      deep: true,
      handler(val) {
        if (val.__params) {
          const newQuery = this.$crypto.Decrypt(val.__params);
          // 在vue原型上定义一个
          Vue.prototype.$route_query = JSON.parse(newQuery);
          return;
        }
        Vue.prototype.$route_query = val || {};
      }
    }
  },
  </script>

6.页面中使用取值

// 路由跳转传参
this.$router.push({
path: "/viewNoticeSimpleDetail",
  query: {
    id:123
  },
});
// 加密前接收参数
this.$route.query.id // 123

// 加密后接收参数
this.$route_query.id // 123

你可能感兴趣的:(页面传值-router,vue.js,前端,安全,同态加密)