如何将加密和解密函数应用到实际项目中?

简介: 如何将加密和解密函数应用到实际项目中?

在实际项目中,将加密和解密函数应用到 Pinia 状态管理中,需要结合插件机制实现自动化加密存储,并确保代码可维护、安全性可控。以下是分步骤的落地方案:

第一步:准备加密工具函数

先创建独立的加密解密工具(复用之前的实现,确保密钥安全):

// src/utils/crypto.js
import CryptoJS from 'crypto-js';

// 生产环境:从后端接口动态获取密钥(这里仅示例)
// 注意:密钥必须是16/24/32字节,IV为16字节
let SECRET_KEY = CryptoJS.enc.Utf8.parse('temp-key-16byte'); // 临时密钥
let IV = CryptoJS.enc.Utf8.parse('temp-iv-16byte__');

// 动态更新密钥(例如登录后从后端获取)
export const updateCryptoKey = (newKey, newIV) => {
   
  SECRET_KEY = CryptoJS.enc.Utf8.parse(newKey);
  IV = CryptoJS.enc.Utf8.parse(newIV);
};

// 加密
export const encrypt = (data) => {
   
  if (!data) return '';
  try {
   
    const dataStr = typeof data === 'string' ? data : JSON.stringify(data);
    return CryptoJS.AES.encrypt(dataStr, SECRET_KEY, {
   
      iv: IV,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }).toString();
  } catch (error) {
   
    console.error('加密失败:', error);
    return '';
  }
};

// 解密
export const decrypt = (encryptedStr) => {
   
  if (!encryptedStr) return null;
  try {
   
    const bytes = CryptoJS.AES.decrypt(encryptedStr, SECRET_KEY, {
   
      iv: IV,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    });
    const decryptedStr = bytes.toString(CryptoJS.enc.Utf8);
    return decryptedStr ? JSON.parse(decryptedStr) : null;
  } catch (error) {
   
    console.error('解密失败:', error);
    return null;
  }
};

第二步:创建 Pinia 加密插件

通过 Pinia 插件自动监听状态变化,实现“状态修改时加密存储,初始化时解密读取”:

// src/plugins/piniaEncrypt.js
import {
    encrypt, decrypt } from '@/utils/crypto';

/**
 * 创建加密存储插件
 * @param {Object} options - 配置项
 * @param {Storage} options.storage - 存储方式(localStorage/sessionStorage)
 * @param {string[]} options.include - 需要加密的store名称列表(空则全部加密)
 */
export const createEncryptPlugin = (options = {
   }) => {
   
  const {
    storage = localStorage, include = [] } = options;

  return (context) => {
   
    const {
    store } = context;
    const storeName = store.$id;

    // 判断当前store是否需要加密(include为空则全部加密)
    const shouldEncrypt = include.length === 0 || include.includes(storeName);
    if (!shouldEncrypt) return;

    // 1. 初始化:从存储中解密数据并同步到store
    const loadEncryptedData = () => {
   
      const encryptedData = storage.getItem(`pinia_${
     storeName}`);
      if (encryptedData) {
   
        const decryptedData = decrypt(encryptedData);
        if (decryptedData) {
   
          store.$patch(decryptedData); // 合并解密后的数据到状态
        }
      }
    };

    // 2. 监听状态变化:自动加密存储
    const saveEncryptedData = () => {
   
      const state = store.$state; // 获取当前状态
      const encryptedData = encrypt(state);
      storage.setItem(`pinia_${
     storeName}`, encryptedData);
    };

    // 初始化加载数据
    loadEncryptedData();

    // 监听状态变化并保存(防抖避免频繁存储)
    let debounceTimer;
    store.$subscribe(() => {
   
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(saveEncryptedData, 100); // 100ms防抖
    });

    // 3. 给store添加手动加密存储的方法
    store.$encryptSave = saveEncryptedData;
    store.$clearEncryptedStorage = () => {
   
      storage.removeItem(`pinia_${
     storeName}`);
    };
  };
};

第三步:在项目中配置 Pinia 并应用插件

在 Pinia 初始化时注册加密插件,指定需要加密的 store:

// src/store/index.js
import {
    createPinia } from 'pinia';
import {
    createEncryptPlugin } from '@/plugins/piniaEncrypt';

const pinia = createPinia();

// 应用加密插件:只加密user和settings两个store
pinia.use(createEncryptPlugin({
   
  storage: localStorage, // 可选:使用sessionStorage
  include: ['user', 'settings'] // 指定需要加密的store名称
}));

export default pinia;

第四步:定义需要加密的 Store

创建普通的 Pinia Store,插件会自动对其状态进行加密处理:

// src/store/user.js
import {
    defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
   
  state: () => ({
   
    token: '',
    userInfo: {
   
      id: '',
      name: '',
      phone: '' // 敏感信息,需要加密
    }
  }),
  actions: {
   
    login(data) {
   
      this.token = data.token;
      this.userInfo = data.userInfo;
      // 状态变化后会自动加密存储,无需手动调用
    },
    logout() {
   
      this.$reset();
      this.$clearEncryptedStorage(); // 清除存储的加密数据
    }
  }
});

第五步:在组件中使用(无需关心加密细节)

组件中正常使用 Store,加密/解密逻辑由插件自动处理:

<!-- src/views/Login.vue -->
<template>
  <button @click="handleLogin">登录</button>
</template>

<script setup>
import { useUserStore } from '@/store/user';
import { updateCryptoKey } from '@/utils/crypto';

const userStore = useUserStore();

const handleLogin = async () => {
  // 1. 调用登录接口,获取用户数据和动态密钥
  const loginRes = await api.login({ username: 'test', password: '123' });
  const { token, userInfo, cryptoKey, cryptoIV } = loginRes.data;

  // 2. 更新加密密钥(关键:生产环境必须动态获取密钥)
  updateCryptoKey(cryptoKey, cryptoIV);

  // 3. 更新状态(插件会自动加密存储)
  userStore.login({ token, userInfo });
};
</script>

核心要点与安全实践

  1. 密钥动态获取
    生产环境中,SECRET_KEYIV 必须通过后端接口动态返回(例如用户登录后),绝对不能硬编码在前端代码中(避免被打包暴露)。

  2. 按需加密
    通过插件的 include 配置,只对包含敏感信息的 Store(如 user)加密,普通 Store(如 theme)无需加密,减少性能损耗。

  3. 防抖动存储
    状态频繁变化时(如输入框),通过防抖(setTimeout)避免加密存储操作过于频繁,优化性能。

  4. 异常处理
    加解密函数中添加错误捕获,避免因密钥错误或数据损坏导致整个应用崩溃。

  5. 数据清除
    用户登出时,不仅要重置状态,还要调用 $clearEncryptedStorage 清除本地加密数据,防止信息泄露。

通过这种方式,加密解密逻辑与业务代码解耦,既保证了敏感数据的安全性,又不影响开发体验。

相关文章
|
7天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
5天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
311 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
18天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1328 8
|
4天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
17天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1406 87
|
6天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
311 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
5天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
6天前
|
弹性计算 安全 数据安全/隐私保护
2025年阿里云域名备案流程(新手图文详细流程)
本文图文详解阿里云账号注册、服务器租赁、域名购买及备案全流程,涵盖企业实名认证、信息模板创建、域名备案提交与管局审核等关键步骤,助您快速完成网站上线前的准备工作。
251 82
2025年阿里云域名备案流程(新手图文详细流程)