vue路由加密方案
大约 2 分钟
vue路由加密方案
在Vue项目中解决URL参数明文传输问题,可通过以下方案实现参数加密,防止用户篡改:
通过自定义Vue Router的stringifyQuery和parseQuery方法,实现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);
};
自定义路由序列化方法 修改路由配置的stringifyQuery和parseQuery:
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: '测试任务' }
}
}