vue路由加密方案

lishihuan大约 2 分钟

vue路由加密方案

在Vue项目中解决URL参数明文传输问题,可通过以下方案实现参数加密,防止用户篡改:

通过自定义Vue RouterstringifyQueryparseQuery方法,实现URL参数的自动加密与解密

1. 使用crypto-js库封装AES加密方法(CBC模式 + PKCS7填充)

封装加密工具 使用crypto-js库封装AES加密方法(CBC模式 + PKCS7填充):

JavaScript// utils/encryption.js
import CryptoJS from 'crypto-js';
const key = CryptoJS.enc.Utf8.parse('16位密钥'); 
const iv = CryptoJS.enc.Utf8.parse('16位偏移量');

export const encrypt = (str) => {
  return CryptoJS.AES.encrypt(str, key, { iv, mode: CryptoJS.mode.CBC }).toString();
};

export const decrypt = (ciphertext) => {
  return CryptoJS.AES.decrypt(ciphertext, key, { iv, mode: CryptoJS.mode.CBC }).toString(CryptoJS.enc.Utf8);
};

自定义路由序列化方法 修改路由配置的stringifyQueryparseQuery

JavaScript// router/index.js
import { encrypt, decrypt } from '@/utils/encryption';

const stringifyQuery = (query) => {
  const str = Object.keys(query).map(k => `${k}=${query[k]}`).join('&');
  return encrypt(str); // 加密整个参数字符串
};

const parseQuery = (encryptedStr) => {
  const decrypted = decrypt(encryptedStr);
  return decrypted.split('&').reduce((acc, pair) => {
    const [key, val] = pair.split('=');
    acc[key] = val;
    return acc;
  }, {});
};

const router = new VueRouter({
  mode: 'history',
  routes,
  stringifyQuery,
  parseQuery
});

效果示例:

  • 原始URL: http://127.0.0.1:8080?taskId=175&modeType=1
  • 加密后URL: http://127.0.0.1:8080?U2FsdGVkX1+3a5YJt7V4v3y7gK7z6w... 解密后实际参数:taskId=175&modeType=1

2. Base64 编码 + 字符混淆方案 【推荐】

  • 编码工具函数封装
// src/utils/encryption.js
export const stringifyQuery = (params) => {
  // 将对象转换为键值对字符串(示例:taskId=175&modeType=1)
  const queryStr = new URLSearchParams(params).toString();
  if (!queryStr) {
    return '';
  }
  // Base64编码 + 符号替换(兼容URL)
  return `?${btoa(queryStr)
    .replace(/\+/g, '_')   // 替换+为_
    .replace(/\//g, '-')   // 替换/为-
    .replace(/=+$/, '')}`;   // 删除末尾的等号(可选)
};

export const parseQuery = (encodedStr) => {
    if(!encodedStr){
    return {}; // 返回空对象或默认值
  }
  // 这边处理并不理想,但是不会导致报错
  if(encodedStr.startsWith('redirect=')){ // 兼容redirect参数
    return encodedStr; // 返回原始字符串
  }
  // 还原符号 + 补全等号
  let str = encodedStr
    .replace(/_/g, '+')
    .replace(/-/g, '/');
  // 补足Base64长度(4的倍数)
  while (str.length % 4) str += '=';

  try {
    const decoded = atob(str);
    return Object.fromEntries(new URLSearchParams(decoded));
  } catch (e) {
    console.error('参数解码失败:', e);
    return {}; // 返回空对象或默认值
  }
};
  • Vue Router全局配置(自动编解码)
// src/router/index.js
import {parseQuery, stringifyQuery} from "@/utils/encryption";

const router = new VueRouter({
  mode: 'history',
  routes: [...],
  stringifyQuery: stringifyQuery,
  parseQuery: parseQuery,
});

实际使用示例

  • 手动拼接加密URL跳转
// 组件内跳转
this.$router.push({
  path: '/detail',
  query: { 
    taskId: 175, 
    modeType: 1,
    taskName: '测试任务'
  }
});

// 生成的URL自动变为:
http://127.0.0.1:8080/detail?dGFza0lkPTE3NSZtb2RlVHlwZT0xJnRhc2tOYW1lPSVFNyVCRCVBQyVFOCVBOSVBNiVFNCVCQiVCQiVFNSU4QiU5OQ
  • 读取解密后的参数
// 目标组件获取参数
export default {
  mounted() {
    // 直接获取解码后的原始参数
    console.log(this.$route.query); 
    // 输出:{ taskId: '175', modeType: '1', taskName: '测试任务' }
  }
}