当前位置: 首页 > news >正文

android 网络拦截器统一处理请求参数和返回值加解密实现

前言

项目中遇到参数加密和返回结果加密的业务
这里写一下实现 一来加深记忆 二来为以后参考铺垫

需求

项目在开发中涉及到 登陆 发验证码 认证 等前期准备接口
这些接口需要单独处理 比如不加密 或者有其他的业务需求

剩下的是登陆成功以后的业务需求接口 针对入参和返回值做了RSA AES加密
需求大概是这样 下面看下代码实现逻辑

实现

在网络框架的配置类里添加加密拦截器

 HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory();OkHttpClient.Builder mOkHttpBuilder = new OkHttpClient.Builder().connectTimeout(CONN_TIME_OUT, TimeUnit.SECONDS).readTimeout(READ_TIME_OUT, TimeUnit.SECONDS).writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS).sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager).addInterceptor(new EncryptionInterceptor()) //加密拦截器 统一处理

解析

我的业务场景是 前期的 登陆 发验证码 认证 接口不需要做加密
所以我需要在加密拦截器前期做单独处理

 		 //认证接口不处理加密需求if (url.encodedPath().equals("xxx/auth")) {return chain.proceed(request);}//登陆和验证码都是get接口所以在这里统一拦截 if (method.equals("get") || method.equals("delete")) {return chain.proceed(request);}

处理完特殊业务场景 就剩统一的post接口 参数统一封装成body

 		 //请求接口请求参数String param = InterceptorUtils.bodyToString(request);//获取加密的keyString aesKey = Hawk.get(AppCode.AES_EKY);String encryptData = AESUtils.encrypt(param, aesKey);//拿到加密后的json字符串String json = new Gson().toJson(new JsonRequest(encryptData));RequestBody body = RequestBody.create(request.body().contentType(), json);request = request.newBuilder().post(body).build();Response response = chain.proceed(request);

下图是加密后的参入 统一用data作为加密key-valuekey用于后端解析
1
再来看一下返回值解密的代码实现 这里有2个点需要注意一下
对于后端返回的类型 无非是对象Object或者数组Array 2种情况 统一封装
先来看一下返回的加密格式

 {"code":20000,"data":"N1bBAjZ4m6PGGWJmu53PzSOcyjjUL0Jo3UITcEgmxYWcnBZSXKXRK81bS65JVoB8ouAuBLSSQvzVxHAc/pRbdUentgpppoe8wfhKvLuVu9LhVPK9y6I9/rf5nNm4h0+R62ubdUNINLsi6tl+j/Gn/gMPAzIoEFtVyQMQvHJ1sH4uh4as0Tnxu51aEknNc8Pm","errorId":"","message":"操作成功"}

2
上图中,data是我们的业务返回数据 它可能是Array也可能是Object
encryptData 加密字符串

	//说明是数组if (encryptData != null && encryptData.startsWith("[")) {JSONArray jsonArray = JSONArray.parseArray(encryptData);decryptObj.setData(jsonArray);} else if (encryptData != null && encryptData.startsWith("{")) {//说明是对象JSONObject jsonObject = JSONObject.parseObject(encryptData);decryptObj.setData(jsonObject);}

EncryptionInterceptor 实现

public class EncryptionInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();okhttp3.HttpUrl url = request.url();String method = request.method().toLowerCase().trim();//认证接口不处理加密需求if (url.encodedPath().equals("/isp/app/worker/auth")) {return chain.proceed(request);}if (method.equals("get") || method.equals("delete")) {return chain.proceed(request);}//请求接口请求参数String param = InterceptorUtils.bodyToString(request);//获取加密的keyString aesKey = Hawk.get(AppCode.AES_EKY);String encryptData = AESUtils.encrypt(param, aesKey);//拿到加密后的json字符串String json = new Gson().toJson(new JsonRequest(encryptData));RequestBody body = RequestBody.create(request.body().contentType(), json);request = request.newBuilder().post(body).build();Response response = chain.proceed(request);return Decrypt(response);}/*** 返回值解密* @param response 返回值* @return response*/private Response Decrypt(Response response) {try {Response.Builder builder = response.newBuilder();Response clone = builder.build();//成功 判断是否等于200if (clone.code() != 200) {return response;}ResponseBody body = clone.body();if (body != null) {MediaType mediaType = body.contentType();if (mediaType != null) {if (InterceptorUtils.isText(mediaType)) {String aesKey = Hawk.get(AppCode.AES_EKY);BaseResult result = new Gson().fromJson(body.string(),BaseResult.class);String encryptData = AESUtils.decrypt(result.getData().toString(), aesKey);ALog.e("解密返回数据 ->" + encryptData);BaseResult decryptObj = new BaseResult();decryptObj.setCode(result.getCode());decryptObj.setErrorId(result.getErrorId());decryptObj.setMessage(result.getMessage());//说明是数组if (encryptData != null && encryptData.startsWith("[")) {JSONArray jsonArray = JSONArray.parseArray(encryptData);decryptObj.setData(jsonArray);} else if (encryptData != null && encryptData.startsWith("{")) {//说明是对象JSONObject jsonObject = JSONObject.parseObject(encryptData);decryptObj.setData(jsonObject);}String strJson = new Gson().toJson(decryptObj);body = ResponseBody.create(mediaType, strJson);return response.newBuilder().body(body).build();}}}} catch (Exception e) {ALog.e("解密错误:" + e.getMessage());}return response;}
}

有什么问题欢迎交流~

相关文章:

android 网络拦截器统一处理请求参数和返回值加解密实现

前言 项目中遇到参数加密和返回结果加密的业务 这里写一下实现 一来加深记忆 二来为以后参考铺垫 需求 项目在开发中涉及到 登陆 发验证码 认证 等前期准备接口 这些接口需要单独处理 比如不加密 或者有其他的业务需求 剩下的是登陆成功以后的业务需求接口 针对入参和返回值…...

Jmeter直连mysql数据库教程

mysql数据库能够通过Navicat等远程连接工具连接 下载驱动并加入jmeter 1.mysql驱动下载地址:MySQL :: Download MySQL Connector/J (Archived Versions) 找到对应的驱动下载:如下图: 把驱动jar包加入jmeter 配置jmeter连接mysql数据库…...

2024美赛数学建模B题思路分析 - 搜索潜水器

1 赛题 问题B:搜索潜水器 总部位于希腊的小型海上巡航潜艇(MCMS)公司,制造能够将人类运送到海洋最深处的潜水器。潜水器被移动到该位置,并不受主船的束缚。MCMS现在希望用他们的潜水器带游客在爱奥尼亚海底探险&…...

Tomcat在Java web的应用

Tomcat在Java web的应用 本来这篇博客顺应之前的内容,应该是需要写Tomcat的简介、基本使用、配置和部署项目、Web的项目结构、创建MavenWeb、idea本地集成以及Tomcat的Maven插件的笔记内容,但是总觉得没必要,因为这些内容网上肯定很多了&…...

Python爬虫某云免费音乐——多线程批量下载

重点一:每首音乐的下载地址 重点二:如何判断是免费音乐 重点三:如何用线程下载并保存 重点四:如何规避运行错误导致子线程死掉 重点五:如何管理子线程合理运行 需要全部代码的私信或者VX:Kmwcx1109 运行效果&…...

Python实现TCP和UDP通信

目录 一:TCP 二:UDP 一:TCP 在Python中实现TCP通信可以通过使用内置的socket模块来完成。以下是一个简单的示例,展示了如何使用Python的socket模块创建一个TCP客户端和服务器。 TCP服务器 import socket def start_server(): s…...

用HTML5 + JavaScript实现下雪效果

用HTML5 JavaScript实现下雪效果 下面是用HTML5 JavaScript实现下雪效果示例&#xff0c;展示了如何使用 HTML5 的 <canvas> 元素以及 JavaScript 来创建下雪效果。效果如下&#xff1a; 源码如下&#xff1a; <!DOCTYPE html> <html lang"en">…...

PDF操作——批量删除末页

一、说明 由于PDF末页为空白页或者是免责声明需要删除&#xff0c;涉及的文件比较多&#xff0c;因此写了一小段代码进行处理。 二、完整架构流程 这个代码的整体架构流程可以分为以下几个步骤&#xff1a; 导入所需的库&#xff1a;首先&#xff0c;代码导入了PyPDF2和os两…...

Jasperreport 生成 PDF之省纸模式

省纸模式顾名思义就是节省纸张&#xff0c;使用 Jasper 去生成 PDF 的时候如果进行分组打印的时候&#xff0c;一页 A4 纸只会打印一组数据。这种情况下&#xff0c;如果每组数据特别少&#xff0c;只有几行&#xff0c;一页 A4 纸张根本用不了&#xff0c;就会另起一页继续打印…...

IDEA反编译Jar包

反编译步骤 使用IDEA安装decompiler插件 找到decompiler插件文件夹所在位置&#xff08;IDEA安装路径/plugins/java-decompiler/lib &#xff09;&#xff0c;将需要反编译的jar包放到decompiler插件文件夹下&#xff0c;并创建一个空的文件夹&#xff0c;用来存放反编译后的…...

MySQL 备份恢复

1.1 MySQL日志管理 在数据库保存数据时&#xff0c;有时候不可避免会出现数据丢失或者被破坏&#xff0c;这样情况下&#xff0c;我们必须保证数据的安全性和完整性&#xff0c;就需要使用日志来查看或者恢复数据了。 数据库中数据丢失或被破坏可能原因&#xff1a; 误删除数…...

UbuntuServer22.04LTS在线安装MySQL8.x

UbuntuServer22.04LTS在线安装MySQL8.x 文章目录 UbuntuServer22.04LTS在线安装MySQL8.x1. 安装1. 官网2. 在线安装3. 修改密码及设置远程登录4. 其他配置参考 2. 启动和停止1. 查看运行状态2. 开机自启3. 查看默认服务器配置命令 3. 登录 1. 安装 1. 官网 官网安装文档&#…...

GmSSL - GmSSL的编译、安装和命令行基本指令

文章目录 Pre下载源代码(zip)编译与安装SM4加密解密SM3摘要SM2签名及验签SM2加密及解密生成SM2根证书rootcakey.pem及CA证书cakey.pem使用CA证书签发签名证书和加密证书将签名证书和ca证书合并为服务端证书certs.pem&#xff0c;并验证查看证书内容&#xff1a; Pre Java - 一…...

面试题:为什么MySQL不建议使用NULL作为列默认值?

文章目录 前言介绍总结 前言 今天来分享一道美团高频面试题&#xff0c;5 分钟搞懂“为什么 MySQL 不建议使用 NULL 作为列默认值&#xff1f;”。 对于这个问题&#xff0c;通常能听到的答案是 使用了 NULL 值的列将会使索引失效,但是如果实际测试过一下,你就知道IS NULL会使…...

ClickHouse基于数据分析常用函数

文章标题 一、WITH语法-定义变量1.1 定义变量1.2 调用函数1.3 子查询 二、GROUP BY子句&#xff08;结合WITH ROLLUP、CUBE、TOTALS&#xff09;三、FORM语法3.1表函数3.1.1 file3.1.2 numbers3.1.3 mysql3.1.4 hdfs 四、ARRAY JOIN语法&#xff08;区别于arrayJoin(arr)函数&a…...

c语言编译和链接

文章目录 翻译环境和运⾏环境编译预处理编译词法分析语法分析语义分析 汇编 链接地址和空间分配符号决议重定位 翻译环境和运⾏环境 在c语言标准&#xff08;ANSI C&#xff09;中的任何⼀种实现中&#xff0c;存在两个不同的环境。 翻译环境&#xff1a;在这个环境中将人写的…...

C++ printf解释

在C中&#xff0c;printf 是一个用于格式化输出的函数。它是C语言中标准库函数的一部分&#xff0c;被继承到了C中。 printf函数的基本语法如下&#xff1a; int printf(const char* format, ...); 其中&#xff0c;format 参数是一个格式化字符串&#xff0c;用于指定输出的…...

paddle环境安装

一、paddle环境安装 如pytorch环境安装一样&#xff0c;首先在base环境下创建一个新的环境来安装paddlepaddle框架。首先创建一个新的环境名叫paddle。执行如下命令。 conda create -n paddle python3.8创建好了名叫paddle这个环境以后&#xff0c;进入到这个环境中&#xff…...

kingbase配置SSL双向认证

SSL简介&#xff1a; SSL属于传输加密&#xff0c;在服务器端和客户端建立加密通信渠道来保证数据安全&#xff0c;防止数据在网络传输过程中被篡改和拦截。SSL加密可以使用第三方证书机构颁发的数字证书&#xff0c;也可以使用自签名证书。这里我们使用自签名证书。 背景&am…...

Android Studio 使用小记2 Flutter提交SVN时需要忽略哪些文件

今天上午发了一篇使用SVN的小记&#xff0c;在解决问题的过程中&#xff0c;发现不少同学在使用Android Studio进行Flutter应用开发时&#xff0c;对需要忽略哪些文件&#xff08;不提交到SVN协同&#xff09;不是很明确&#xff0c;对于这个问题&#xff0c;Flutter官方有明确…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟

众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了&#xff0c;延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp &#xff0c;边缘服务器拉流推送到云服务器 …...

【Redis】Redis从入门到实战:全面指南

Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...