vue2 封装get post请求 加密参数

本文介绍了如何在Vue.js应用中使用Axios进行API请求的封装,包括设置默认配置、请求和响应拦截器,以及处理各种错误情况。同时展示了get和post请求的封装示例,涉及参数加密、登录超时和错误提示等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import axios from 'axios'
import { getStore, removeStroe } from '@/utils/storage'
import { TOKEN_NAME } from '@/config/base'
import app from '@/main'
import store from "../store/index"
import Qs from 'qs'
import Route from '@/router/index'
// 加密解密
import { encrypt, jsonEncrypt } from '@/utils/aesHelper'

axios.defaults.timeout = 30000;
axios.defaults.headers.post['Content-Type'] = 'application/json';
//请求拦截
axios.interceptors.request.use(config => {
        config.headers.Authorization = getStore(TOKEN_NAME);
        if (config.url.indexOf('lgApi') > 0) { //lgApi
            if (config.url.indexOf('checkCaptcha') > 0) {
                config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
            } else {
                config.headers['Content-Type'] = 'application/json'
                config.headers.Authorization = getStore(TOKEN_NAME);
            }
        } else if (config.url.indexOf('pubUpload/fileDownLoad/deleteFile') > 0) {
            config.headers['Content-Type'] = 'application/json'
        } else if (config.url.indexOf("/media/addZhgbMedia") > 0 || config.url.indexOf("/tyApi") > 0) {
            return config
        }

        //所有接口加密方法
        if (config.url.indexOf('checkCaptcha') == -1) {
            paramEncrypt(config);
        }
        return config
    }, error => {
        return Promise.reject(error)
    })
    //参数加密
function paramEncrypt(config) {
    if (config.method == 'get') {
        axios.defaults.headers.post['Content-Type'] = 'application/json';
        let param = Object.assign({}, config.params)
        config.params = jsonEncrypt(param)
    } else if (config.url.indexOf('lgApi') > 0) {
        if (config.url.indexOf('userLogin') > 0) {
            config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
            let jsonObj = Qs.parse(config.data);
            let encryptStr = Qs.stringify(jsonEncrypt(jsonObj))
            config.data = encryptStr
        } else {
            let jsonStr = JSON.stringify(Qs.parse(config.data))
            let encryptStr = encrypt(jsonStr)
            config.data = encryptStr
        }
    } else {
        let jsonStr = JSON.stringify(Qs.parse(config.data))
        let encryptStr = encrypt(jsonStr)
        config.data = encryptStr
    }
}

//响应拦截
axios.interceptors.response.use(response => {
    return response
}, error => {
    return Promise.reject(error.response.data)
})

//封装axios的get请求
export function get(url, params,config) {
    return new Promise((resolve, reject) => {
        axios.get(
                url, { params,...config }
            )
            .then(res => {
                if (validateData(res.data))
                    resolve(res.data)
                else
                    reject(res.data)
            })
            .catch((error) => {
                console.log(error);
                store.commit("SET_LOADING_SHOW", false);
                // 网络错误
                // app.$Message.error('网络错误!');
            })
    })
}

//封装axios的post请求
export function post(url, data = {}) {




    return new Promise((resolve, reject) => {

        axios({
                method: 'post',
                url: url,
                data: Qs.stringify(data)
            })
            .then(res => {
                if (validateData(res.data)) {
                    resolve(res.data);
                }
            })
            .catch((error) => {
                reject(error)
                if (error.error_description == 'Too many failures') {
                    if (document.getElementsByClassName('ivu-message-notice-content-error').length === 0) {
                        app.$Message.warning('用户名或密码错误次数超过5次,请一小时以后重新登录!');

                    }


                } else if (error.error_description == 'invalid username or password, Bad credentials') {
                    if (document.getElementsByClassName('ivu-message-notice-content-error').length === 0) {
                        app.$Message.warning('用户名或密码错误!');

                    }


                } else {
                    // 网络错误

                    // app.$Message.error('网络错误!');
                }
                store.commit("SET_LOADING_SHOW", false);
            })
    })
}

/**
 *
 * @param {校验ajax返回的数据} res
 */
function validateData(res) {
    //查找图片
    if (res == '{code: 500, data: [], msg: "fail"}')
        return true
            // if (!res.token) return true;

    if (!res.code) return true;

    let { code, msg, data } = res
    if (isNaN(code)) {
        return false
    }

    if (code == 2011) {
        removeStroe(TOKEN_NAME)
        if (document.getElementsByClassName('ivu-message-notice-content-error').length === 0) {
            app.$Message.error('登录超时,请重新登录!')

        }

        Route.push('/login')
    }
    if (!(code == 0 || code == 500 || code == -1)) {
        if (code == 2002) {
            removeStroe(TOKEN_NAME)

            if (document.getElementsByClassName('ivu-message-notice-content-error').length === 0) {
                app.$Message.error('该账号已在其他浏览器登录!如非本人操作,请立即重新登录并修改密码!')

            }

            Route.push('/login')
        } else {
            return true
        }
    }
    return true
}

使用

import { get,post } from "@/axios/http";
/**********************************************************************/
//一键报警列表
export function getAlarmInfoPage(pageObj) {
    return get("/informationApi/alarmInfo/getAlarmInfoPage", pageObj)
}
//一键报警审核详情
export function getAuditDetail(pageObj) {
    return get("/informationApi/alarmInfo/getAuditDetail", pageObj)
}
//保存党建活动
export function saveAlarmAuditInfo(pageObj) {
    return post("/informationApi/alarmInfo/auditSave", pageObj)
}

<think>首先,用户的问题是关于在Vue2和SpringBoot构建的前后端分离应用中实现接口参数加密和解密。我需要参考提供的引用,但记住这些引用是关于数据加密的,比如[^1]提到Vue+SpringBoot实现前后端数据加解密,[^2]是关于路由配置,[^3]是关于JWT加密整合。 关键点: - 用户要求实现接口参数加密和解密。 - 系统级指令:我必须使用$...$格式表示行内数学表达式,$$...$$格式表示独立公式,并确保LaTeX语法正确。使用中文回答,生成相关问题。 - 回答结构:结构清晰,逐步解决问题,保证真实可靠。 - 引用:在引用的段落末尾自然地添加引用标识,如[^1]。 从引用中提取有用信息: - [^1] 讨论了加密的原因(保护隐私、防止篡改、合规等),并提供了代码示例,包括前端和后端部分。 - [^2] 是关于Vue路由配置,不太直接相关。 - [^3] 是关于JWT验证的拦截器配置。 用户的问题具体是接口参数加密和解密,所以我需要专注于如何加密请求参数和解密响应参数。 步骤: 1. **理解需求**:在前后端分离应用中,前端(Vue2)发送请求加密参数,后端(SpringBoot)解密处理;后端返回数据时加密,前端解密。 2. **常见方法**: - 使用对称加密算法,如AES(高级加密标准),因为它快速且适合数据传输。 - 非对称加密如RSA,但通常用于密钥交换,不直接用于大量数据。 - 结合使用:例如,用RSA加密AES密钥,然后用AES加密数据。 - 在引用[^1]中,提到了SecretUtils,可能涉及AES或类似。 3. **实现步骤**: - **前端(Vue2)**: - 在发送请求前,使用加密函数加密参数。 - 在接收响应后,使用解密函数解密数据。 - 可以使用JavaScript加密库,如CryptoJS。 - **后端(SpringBoot)**: - 在Controller接收请求时,解密参数。 - 在返回响应前,加密数据。 - 可以使用Java加密库,如javax.crypto。 - **密钥管理**:密钥需要安全存储和传输。常见做法是前端和后端共享一个密钥(对称),或使用非对称方式。 4. **参考引用**: - [^1] 提供了前端Secret.js和index.vue的代码示例,以及后端的SecretUtils和DemoController。 - 我需要基于这些构建回答。 - [^3] 的JWT拦截器可以用于验证,但加密是额外的。 回答结构: - 逐步解释如何实现: 1. **引入依赖**:前端和后端需要加密库。 2. **前端加密实现**:在Vue2中,使用axios拦截器或自定义函数加密请求数据。 3. **后端解密实现**:在SpringBoot中,使用过滤器或拦截器解密请求加密响应。 4. **密钥协商**:如何安全地共享密钥。 5. **代码示例**:提供简单示例。 - 确保真实可靠:基于标准实践。 - 添加引用:当提到引用内容时添加[^1]等。 生成相关问题: - 在回答后,添加§§相关问题§§部分,列出3个相关问题。 LaTeX使用:如果有数学表达式,比如在解释算法时,但这里可能不需要复杂的数学。用户提到“包括变量、不等式、方程等”,但在这个上下文中,可能不直接涉及。如果提到加密算法,如AES公式,我可以使用。例如,AES加密可以用$E_k(P)$表示加密函数,其中$k$是密钥,$P$是明文。 最终回答大纲: 1. **引言**:解释为什么需要加密(参考[^1])。 2. **步骤**: - 步骤1:选择加密算法(建议AES)。 - 步骤2:前端实现(Vue2)。 - 步骤3:后端实现(SpringBoot)。 - 步骤4:测试和优化。 3. **代码示例**:提供简化的代码片段。 4. **总结**。 5. **相关问题**。 引用标识:在描述加密原因或代码参考时添加[^1]。 完整回答:</think>### Vue2 与 SpringBoot 前后端分离应用实现接口参数加密和解密 在前后端分离架构中,接口参数加密和解密是保护数据传输安全的关键措施,可防止数据泄露、篡改和未授权访问[^1]。以下我将基于 Vue2(前端)和 SpringBoot(后端)逐步解释实现方法。推荐使用对称加密算法(如 AES),因为它高效且易于实现。整体流程包括: 1. 前端加密请求参数并发送。 2. 后端解密请求参数、处理业务逻辑、加密响应数据。 3. 前端解密响应数据。 整个过程需确保密钥安全(如固定密钥或动态协商)。 #### 步骤 1: 选择加密算法和密钥管理 - **算法选择**:建议使用 AES(Advanced Encryption Standard),因其速度快、安全性高。AES 加密公式可表示为 $E_k(P)$,其中 $k$ 为密钥,$P$ 为明文;解密为 $D_k(C)$,$C$ 为密文。 - **密钥管理**: - 固定密钥:前后端共享一个预定义密钥(如 "mySecretKey123456"),简单但需确保密钥不泄露。 - 动态协商:首次请求时,后端生成随机密钥并用 RSA 加密后传给前端,后续通信使用该密钥进行 AES 加密(更安全)。 - **依赖引入**: - 前端:Vue2 项目安装 CryptoJS 库(AES 实现)。 ```bash npm install crypto-js ``` - 后端:SpringBoot 添加 Java 加密扩展(JCE),无需额外依赖。 #### 步骤 2: 前端(Vue2)实现加密和解密 在 Vue2 中,使用 Axios 拦截器处理请求/响应加解密,避免修改业务代码。 - **创建加密工具类**:在 `src/utils/secret.js` 中定义 AES 加密/解密函数(参考引用[^1])。 ```javascript import CryptoJS from 'crypto-js'; const SECRET_KEY = 'mySecretKey123456'; // 前后端共享密钥 // 加密函数 export function encryptData(data) { const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString(); return encrypted; } // 解密函数 export function decryptData(encryptedData) { const bytes = CryptoJS.AES.decrypt(encryptedData, SECRET_KEY); return JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); } ``` - **配置 Axios 拦截器**:在 `src/main.js` 或单独文件中,修改请求/响应。 ```javascript import axios from 'axios'; import { encryptData, decryptData } from '@/utils/secret'; // 请求拦截器:加密参数 axios.interceptors.request.use(config => { if (config.data) { config.data = { encrypted: encryptData(config.data) }; // 将参数加密封装 } return config; }, error => Promise.reject(error)); // 响应拦截器:解密数据 axios.interceptors.response.use(response => { if (response.data.encrypted) { response.data = decryptData(response.data.encrypted); // 解密响应 } return response; }, error => Promise.reject(error)); ``` - **业务调用**:在 Vue 组件中,正常使用 Axios 发送请求,拦截器自动处理加解密。 ```javascript // 示例:登录请求 this.$axios.post('/api/login', { username: 'admin', password: '123456' }) .then(response => { console.log('解密后数据:', response.data); // 自动解密 }); ``` #### 步骤 3: 后端(SpringBoot)实现解密和加密 在 SpringBoot 中,使用过滤器(Filter)或拦截器(Interceptor)统一处理请求/响应加解密。 - **创建加解密工具类**:在 `com.example.util.SecretUtils` 中(参考引用[^1]和引用[^3])。 ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class SecretUtils { private static final String AES_ALGORITHM = "AES"; private static final String SECRET_KEY = "mySecretKey123456"; // 与前端一致 // 加密方法 public static String encrypt(String data) throws Exception { SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), AES_ALGORITHM); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec); byte[] encryptedBytes = cipher.doFinal(data.getBytes()); return Base64.getEncoder().encodeToString(encryptedBytes); } // 解密方法 public static String decrypt(String encryptedData) throws Exception { SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), AES_ALGORITHM); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec); byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData)); return new String(decryptedBytes); } } ``` - **添加拦截器处理加解密**:创建全局拦截器,在请求进入 Controller 前解密,响应返回前加密。 ```java import com.example.util.SecretUtils; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class EncryptionFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 解密请求(仅处理 POST/PUT) if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) { String encryptedData = request.getReader().lines().reduce("", String::concat); if (!encryptedData.isEmpty()) { String decryptedData = SecretUtils.decrypt(encryptedData); request.setAttribute("decryptedBody", decryptedData); // 存储解密后数据 } } // 继续处理 filterChain.doFilter(request, response); // 加密响应 String responseData = response.getContentType() != null ? response.getContentType() : ""; if (responseData.contains("application/json")) { String originalResponse = response.getOutputStream().toString(); String encryptedResponse = SecretUtils.encrypt(originalResponse); response.getWriter().write(encryptedResponse); } } } ``` - **在 Controller 中使用解密数据**:直接从请求属性获取解密后参数。 ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { @PostMapping("/api/login") public String login(HttpServletRequest request) { String decryptedData = (String) request.getAttribute("decryptedBody"); // 处理业务逻辑,如验证用户 return "success"; // 响应会自动加密 } } ``` #### 步骤 4: 测试和优化 - **测试**:使用 Postman 或前端调试工具验证: - 发送加密请求:确保参数为密文格式。 - 接收响应:检查是否返回密文,前端能否正确解密。 - **优化建议**: - **性能**:AES 加密对性能影响小,但高频请求下可缓存密钥。 - **安全**:避免硬编码密钥,使用环境变量或配置中心存储。 - **错误处理**:添加异常捕获(如解密失败返回 400 错误)。 - **结合 JWT**:如引用[^3]所示,可整合 JWT 进行身份验证,加密负责数据安全。 #### 总结 通过上述步骤,您可以在 Vue2 和 SpringBoot 应用中实现接口参数的全流程加解密。核心是使用 AES 算法,并借助拦截器统一处理,减少代码侵入。此方法适用于敏感数据传输场景,如登录、支付等[^1]。实际部署时,务必定期轮换密钥以提升安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值