鸿蒙ArkTs使用axios发起网络请求并对请求参数加密

ops/2024/9/26 1:23:36/

下载安装axios

ohpm install @ohos/axios

需要权限

{"module": {"requestPermissions": [{"name": "ohos.permission.INTERNET","reason": "$string:permission_internet","usedScene": {"abilities": ["EntryAbility"],//inuse(使用时)、always(始终)。"when": "inuse"}}]}
}

AES加密数据:

  //参数排序后序列化let jsonParams: string = JSON.stringify(obj)Logger.debug(TAG, jsonParams)//生成aes秘钥//创建秘钥生成器let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256')// 通过非对称密钥生成器,随机生成非对称密钥let promiseSymKey = symKeyGenerator.generateSymKeySync();//转换成可以读懂的字符串let key = buffer.from(promiseSymKey.getEncoded().data).toString('hex').substring(0, 32);//创建ivlet iv = key.substring(0, 16);let ivParam: cryptoFramework.IvParamsSpec = {algName: 'IvParamsSpec',iv: {data: new Uint8Array(buffer.from(iv).buffer)}}//convertKey方法是通过秘钥生成symKeylet symKey = symKeyGenerator.convertKeySync({ data: new Uint8Array(buffer.from(key).buffer) });//创建cipherlet cipher = cryptoFramework.createCipher('AES256|CBC|PKCS7');//创建cipher之后才能初始化cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivParam);let output = cipher.doFinalSync({ data: new Uint8Array(buffer.from(jsonParams, 'utf-8').buffer) })let base64: util.Base64Helper = new util.Base64Helper();//加密后的数据let aesParams = base64.encodeToStringSync(output.data);

RSA加密数据:

  //RSA加密aes秘钥//将公钥转换let symKeyBlob: crypto.DataBlob = { data: base64.decodeSync(PUBLIC_KEY) };let aesGenerator = crypto.createAsyKeyGenerator('RSA1024');let pubPair = aesGenerator.convertKeySync(symKeyBlob, null);//生成加密器let encoder = crypto.createCipher('RSA1024|PKCS1');//初始化加密环境encoder.initSync(crypto.CryptoMode.ENCRYPT_MODE, pubPair.pubKey, null);//封装加密所需数据let encode = new util.TextEncoder();//开始加密let updateOutput = encoder.doFinalSync({ data: encode.encodeInto(key) });//转换字符串let rsaKay = buffer.from(updateOutput.data).toString("base64");//写入请求头config.headers[CryptoConstant.PRIVATE_KEY] = rsaKay;

加载中弹窗

import { ComponentContent, PromptAction } from '@kit.ArkUI';class LoadingManager {contentNode: ComponentContent<Object> | undefined = undefined;promptAction: PromptAction | undefined = undefined;isShowing: number = 0show(uiContext: UIContext) {this.isShowing++;this.contentNode = new ComponentContent(uiContext, wrapBuilder(Loading));this.promptAction = uiContext.getPromptAction();this.promptAction.openCustomDialog(this.contentNode, {alignment: DialogAlignment.Center})}hide() {this.isShowing--;if (this.isShowing <= 0) {if (this.promptAction) {this.promptAction.closeCustomDialog(this.contentNode)}}}
}let loadingManager = new LoadingManager()export default loadingManager;@Builder
function Loading() {Column() {LoadingProgress().width($r('app.string.dimensions_50')).height($r('app.string.dimensions_50')).color(Color.White)}.width($r('app.string.dimensions_50')).height($r('app.string.dimensions_50')).backgroundColor($r('app.color.bg_00000000')).justifyContent(FlexAlign.Center)
}

完整AxiosHttp.ets

import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig, Method } from '@ohos/axios';import { GlobalThis, Logger, StringBuilder, StrUtil, ToastUtil } from '@yunkss/eftool';
import { ResponseBaseResult, ResponseResult } from '../model/ResponseResult';
import { deviceInfo, emitter, systemDateTime } from '@kit.BasicServicesKit';
import { ContentType } from '../constant/CommonConstant';
import { HttpConstant } from '../constant/HttpConstant';
import { HttpConfig } from '../utils/HttpConfig';
import { UserManager } from './UserManager';
import { buffer, TreeMap, util } from '@kit.ArkTS';
import { CryptoConstant } from '../constant/CryptoConstant';
import BuildProfile from '../../../../BuildProfile';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { EmitterConstants } from '../constant/EmitterConstants';
import loadingManager from './LoadingManager';
import crypto from '@ohos.security.cryptoFramework';const TAG: string = "HttpUtil:  "
const PUBLIC_KEY = "MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGj8WNUSzCn0rHqfIXk9XPdJp60u\n" +"JnM+mVZVxY1lZmUCVA7t3eJZ0R0z1hUHkVb51eryDZcsz0QLSav3cmQv00ullK18\n" +"8aOs2SXZe6rcQf6XmOsVBqgADkrN+WePZJmb5Fr0NUkQ/sr7+R71cDZ87Y9QKm99\n" +"8BFOiWoEGxWWvDsTAgMBABF=";export function httpDefaultSetting() {// default settingsaxios.defaults.baseURL = HttpConfig.BASE_URL;axios.defaults.timeout = HttpConstant.HTTP_TIMEOUT;// default headers//设备相关axios.defaults.headers.common['os'] = 'harmoney';axios.defaults.headers.common['device'] = deviceInfo.marketName;//用户相关axios.defaults.headers.common["token"] = UserManager.getToken();axios.defaults.headers.common["Authorization"] = UserManager.getToken();// for postaxios.defaults.headers.post['Content-Type'] = ContentType.APPLICATION_JSON// 添加请求拦截器axios.interceptors.request.use((config: InternalAxiosRequestConfig) => {return transRequest(config);}, (error: AxiosError) => {return Promise.reject(error);});// 添加响应拦截器axios.interceptors.response.use((response: AxiosResponse) => {return transResponse(response);}, (error: AxiosError) => {return Promise.reject(error);});
}/*** 在这里处理请求体的拦截器操作逻辑*/
async function transRequest(config: InternalAxiosRequestConfig): Promise<InternalAxiosRequestConfig> {try {Logger.debug(TAG, "------------------Request------------------");Logger.debug(TAG, "httpUrl: " + config.baseURL + config.url);Logger.debug(TAG, "headers: " + JSON.stringify(config.headers));syncCryptoDataBySys(config)} catch (error) {let e: Error = error as ErrorLogger.error(TAG, e.message)} finally {return config;}
}/*** 在这里处理请求结果的拦截器操作逻辑*/
function transResponse(response: AxiosResponse): AxiosResponse {try {if (isSuccess(response)) {let data: ResponseBaseResult = response.data as ResponseBaseResultswitch (data.code) {case HttpConstant.HTTP_OK:case HttpConstant.HTTP_OK_200:breakcase HttpConstant.HTTP_LOGOUT:// 退出登录emitter.emit({ eventId: EmitterConstants.LOGIN_OUT }, {data: {msg: data.msg,}});breakdefault:if (data.msg != null && data.msg.length != 0) {ToastUtil.showToast(data.msg)}break}} else {ToastUtil.showToast(!StrUtil.isEmpty(response.statusText) ? response.statusText : $r('app.string.http_error_msg'))}return response;} catch (error) {let e: Error = error as ErrorToastUtil.showToast(!StrUtil.isEmpty(e.message) ? e.message : $r('app.string.http_error_msg'))return response;}
}export function httpGet<D>(url: string, config?: AxiosRequestConfig<D>,): Promise<D> {Logger.debug(TAG, "httpGet: ");let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()if (uiContext != undefined) {loadingManager.show(uiContext)}return new Promise<D>((resolve: Function, reject: Function) => {let startTime = systemDateTime.getTime()axios.get<ResponseResult<D>, AxiosResponse<ResponseResult<D>>, null>(url, {baseURL: config?.baseURL,headers: config?.headers,// 指定请求超时的毫秒数(0 表示无超时时间)timeout: HttpConstant.HTTP_TIMEOUT,params: config?.params,}).then((response: AxiosResponse<ResponseResult<D>>) => {let duration = (systemDateTime.getTime() - startTime).toString()Logger.debug(TAG, "------------------Response------------------");Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.debug(TAG, "httpGet Success duration=" + duration);Logger.debug(TAG, "config=" + JSON.stringify(response.config));Logger.debug(TAG, "status=" + response.status);Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));Logger.debug(TAG, "data=" + JSON.stringify(response.data));Logger.debug(TAG, "-------------------------------------------");if (isSuccess(response)) {if (isResultSuccess(response.data)) {resolve(response.data.data);} else {const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }reject(e);}} else {const e: Error = { name: `${response.status}`, message: `${response.statusText}` }reject(e);}loadingManager.hide()}).catch((reason: AxiosError) => {Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.error(TAG, JSON.stringify(reason));reject(reason)loadingManager.hide()})});
}export function httpPost<D>(url: string, data?: ESObject, config?: AxiosRequestConfig<D>,isFormUrlencoded: boolean = true): Promise<D> {let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()if (uiContext != undefined) {loadingManager.show(uiContext)}return new Promise<D>((resolve: Function, reject: Function) => {let startTime = systemDateTime.getTime()let requestData: ESObject = isFormUrlencoded ? getRequestFormData(data ?? config?.data) : data ?? config?.dataaxios.post(url,requestData,{baseURL: config?.baseURL,headers: buildPostRequestHeader(isFormUrlencoded, config?.headers),// 指定请求超时的毫秒数(0 表示无超时时间)timeout: HttpConstant.HTTP_TIMEOUT,params: config?.params,}).then((response: AxiosResponse<ResponseResult<D>>) => {let duration = (systemDateTime.getTime() - startTime).toString()Logger.debug(TAG, "------------------Response------------------");Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.debug(TAG, "httpPost Success duration=" + duration);Logger.debug(TAG, "config=" + JSON.stringify(response.config));Logger.debug(TAG, "status=" + response.status);Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));Logger.debug(TAG, "data=" + JSON.stringify(response.data));Logger.debug(TAG, "-------------------------------------------");if (isSuccess(response)) {if (isResultSuccess(response.data)) {resolve(response.data.data);} else {const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }reject(e);}} else {const e: Error = { name: `${response.status}`, message: `${response.statusText}` }reject(e);}loadingManager.hide()}).catch((reason: AxiosError) => {Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.error(TAG, JSON.stringify(reason));reject(reason)loadingManager.hide()})})
}export function httpRequest<D>(url: string, method?: Method | string, data?: D,config?: AxiosRequestConfig<D>): Promise<ResponseResult<D>> {let uiContext = GlobalThis.getInstance().getContext("EntryAbility")?.windowStage.getMainWindowSync().getUIContext()if (uiContext != undefined) {loadingManager.show(uiContext)}return new Promise<ResponseResult<D>>((resolve: Function, reject: Function) => {let startTime = systemDateTime.getTime()axios.request<ResponseResult<D>, AxiosResponse<ResponseResult<D>>, D>({url: url,method: method,baseURL: config?.baseURL,headers: config?.headers,// 指定请求超时的毫秒数(0 表示无超时时间)timeout: HttpConstant.HTTP_TIMEOUT,params: config?.params,data: data ?? config?.data}).then((response: AxiosResponse<ResponseResult<D>>) => {let duration = (systemDateTime.getTime() - startTime).toString()Logger.debug(TAG, "------------------Response------------------");Logger.debug(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.debug(TAG, "httpRequest Success duration=" + duration);Logger.debug(TAG, "config=" + JSON.stringify(response.config));Logger.debug(TAG, "status=" + response.status);// Logger.debug(TAG, "statusText=" + response.statusText); // always empty??Logger.debug(TAG, "headers=" + JSON.stringify(response.headers));Logger.debug(TAG, "data=" + JSON.stringify(response.data));Logger.debug(TAG, "-------------------------------------------");if (isSuccess(response)) {if (isResultSuccess(response.data)) {resolve(response.data.data);} else {const e: Error = { name: `${response.data.code}`, message: `${response.data.msg}` }reject(e);}} else {const e: Error = { name: `${response.status}`, message: `${response.statusText}` }reject(e);}loadingManager.hide()}).catch((reason: AxiosError) => {Logger.error(TAG, "httpUrl" + config?.baseURL + config?.url);Logger.error(TAG, JSON.stringify(reason));reject(reason)loadingManager.hide()})});
}function getRequestFormData(data?: ESObject): string | undefined {if (data == undefined) {return undefined;}let sb = new StringBuilder();let keys = Object.keys(data);keys.forEach((key: string) => {sb.append(`${key}=${data[key]}`)if (keys.indexOf(key) != keys.length - 1) {sb.append('&')}})let formData = sb.toString();return formData;
}function buildPostRequestHeader(isFormUrlencoded: boolean,headers?: Record<ESObject, ESObject>): Record<ESObject, ESObject> {if (headers != null) {headers['Content-Type'] = isFormUrlencoded ? ContentType.APPLICATION_FORM : ContentType.APPLICATION_JSONreturn headers}return {'Content-Type': isFormUrlencoded ? ContentType.APPLICATION_FORM : ContentType.APPLICATION_JSON,}
}function isSuccess(response: AxiosResponse): boolean {return response.status >= 200 && response.status < 300
}function isResultSuccess(result: ResponseBaseResult): boolean {return result.code == HttpConstant.HTTP_OK
}// 同步加密数据
export function syncCryptoDataBySys(config: InternalAxiosRequestConfig) {let treeMap: TreeMap<string, string> = new TreeMap()if (config.headers['Content-Type'] == ContentType.APPLICATION_FORM) {let data = StrUtil.asString(config.data);let params: string[] | undefined = data?.split("&");if (params != undefined) {params.forEach(param => {let paramKV: string[] = param.split("=");treeMap.set(paramKV[0], paramKV[1]);})}} else {let keys = Object.keys(config.data);keys.forEach((key: string) => {treeMap.set(key, config.data[key]);})}let obj: Record<string, string> = {};for (let entry of treeMap.entries()) {obj[Object(entry)[0]] = Object(entry)[1];}//参数排序后序列化let jsonParams: string = JSON.stringify(obj)Logger.debug(TAG, jsonParams)//AES加密//创建秘钥生成器let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256')// 通过非对称密钥生成器,随机生成非对称密钥let promiseSymKey = symKeyGenerator.generateSymKeySync();//转换成可以读懂的字符串let key = buffer.from(promiseSymKey.getEncoded().data).toString('hex').substring(0, 32);//创建ivlet iv = key.substring(0, 16);let ivParam: cryptoFramework.IvParamsSpec = {algName: 'IvParamsSpec',iv: {data: new Uint8Array(buffer.from(iv).buffer)}}//convertKey方法是通过秘钥生成symKeylet symKey = symKeyGenerator.convertKeySync({ data: new Uint8Array(buffer.from(key).buffer) });//创建cipherlet cipher = cryptoFramework.createCipher('AES256|CBC|PKCS7');//创建cipher之后才能初始化cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivParam);let output = cipher.doFinalSync({ data: new Uint8Array(buffer.from(jsonParams, 'utf-8').buffer) })let base64: util.Base64Helper = new util.Base64Helper();//加密后的数据let aesParams = base64.encodeToStringSync(output.data);//写入请求体config.data = encodeURIComponent(CryptoConstant.SIGN) + "=" + encodeURIComponent(aesParams);//RSA加密aes秘钥//将公钥转换let symKeyBlob: crypto.DataBlob = { data: base64.decodeSync(PUBLIC_KEY) };let aesGenerator = crypto.createAsyKeyGenerator('RSA1024');let pubPair = aesGenerator.convertKeySync(symKeyBlob, null);//生成加密器let encoder = crypto.createCipher('RSA1024|PKCS1');//初始化加密环境encoder.initSync(crypto.CryptoMode.ENCRYPT_MODE, pubPair.pubKey, null);//封装加密所需数据let encode = new util.TextEncoder();//开始加密let updateOutput = encoder.doFinalSync({ data: encode.encodeInto(key) });//转换字符串let rsaKay = buffer.from(updateOutput.data).toString("base64");//写入请求头config.headers[CryptoConstant.PRIVATE_KEY] = rsaKay;Logger.debug(TAG, CryptoConstant.SIGN + ": " + aesParams)Logger.debug(TAG, CryptoConstant.PRIVATE_KEY + ": " + rsaKay)
}// 同步加密数据
export function syncCryptoDataByRSA(data: string): string {//RSA加密aes秘钥//将公钥转换let base64: util.Base64Helper = new util.Base64Helper();let symKeyBlob: crypto.DataBlob = { data: base64.decodeSync(PUBLIC_KEY) };let aesGenerator = crypto.createAsyKeyGenerator('RSA1024');let pubPair = aesGenerator.convertKeySync(symKeyBlob, null);//生成加密器let encoder = crypto.createCipher('RSA1024|PKCS1');//初始化加密环境encoder.initSync(crypto.CryptoMode.ENCRYPT_MODE, pubPair.pubKey, null);//封装加密所需数据let encode = new util.TextEncoder();//开始加密let updateOutput = encoder.doFinalSync({ data: encode.encodeInto(data) });//转换字符串return buffer.from(updateOutput.data).toString("base64");
}

接口示例:

  // 登录login() {if (StrUtil.isEmpty(this.phone)) {ToastUtil.showToast($r('app.string.empty_phone_hint'))return}if (StrUtil.isEmpty(this.smsCode)) {ToastUtil.showToast($r('app.string.empty_sms_code_hint'))return}if (!this.isAgreeProtocol) {ToastUtil.showToast($r('app.string.agree_protocol_hint'))return}httpPost<LoginTokenModel>(HttpConfig.LLCB_LOGIN_TO_LOGIN, {phone: this.phone,smsCode: this.smsCode,client_id: LoginConstants.client_id,grant_type: LoginConstants.grant_type_sms,client_secret: LoginConstants.client_secret,userType: LoginConstants.userType,osType: LoginConstants.osType,}, {baseURL: HttpConfig.BASE_URL_THIRD_LOGIN_IP}).then((loginTokenModel) => {Logger.error("LoginPage ", JSONUtil.toJSONString(loginTokenModel))}).catch((e: Error) => {Logger.error("LoginPage ", e.message)})}

http://www.ppmy.cn/ops/100323.html

相关文章

如何利用命令模式实现一个手游后端架构

命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求封装为对象&#xff0c;从而使用不同的请求、队列、日志来参数化其他对象。命令模式也支持可撤销的操作。虽然命令模式在图形用户界面&#xff08;GUI&#xff09;编程中最为常见&a…

设备运维故障排查与修复技巧

运维中最常见的40个故障问题及其解决方法: 1. 网络不通问题:无法访问网络资源。 解决方法:检查物理线路、交换机端口、网卡驱动和配置,使用ping、traceroute等工具定位问题。 2. 网络速度慢问题:访问网络资源速度慢。 解决方法:分析带宽使用情况,检查是否存在广播风…

K8S集群中驱逐节点

K8S集群中驱逐node节点 下面以驱逐节点上的GPU节点为例&#xff1a; 1.驱逐节点上的资源 使用以下命令从节点上驱逐 GPU 资源&#xff1a; kubectl drain <node-name> --delete-local-data --force --ignore-daemonsets说明: <node-name> 是要驱逐 GPU 的节点名…

X86 PVE 下安装路由存储系统iStoreOS

简介 iStoreOS是一个比较易用的路由存储系统&#xff0c;它能让你获得更好的网络及 存储的体验。 系统本身开源免费&#xff0c;目前系统代码开源在&#xff1a;Github iStoreOS 下载固件 固件下载&#xff1a;https://fw.koolcenter.com/iStoreOS/x86_64/ istoreos-22.03.7…

JVM、JRE、JDK

目录 1. JVM&#xff08;Java Virtual Machine&#xff09; 2. JRE&#xff08;Java Runtime Environment&#xff09; 3. JDK&#xff08;Java Development Kit&#xff09; 4.总结 1. JVM&#xff08;Java Virtual Machine&#xff09; JVM是Java虚拟机&#xff0c;它是Java程…

力扣2845.统计趣味子数组的数目

力扣2845.统计趣味子数组的数目 同余 每次都写成ans mp[s%mod]&#xff0c;下意识认为余数相等应该是ans mp[(s-kmodulo)%modulo]; class Solution {public:long long countInterestingSubarrays(vector<int>& nums, int modulo, int k) {int n nums.size();lo…

CSS防止父级边框塌陷的四种方法

1.推荐&#xff1a;加空div 因为父容器只设置了宽度&#xff0c;没设置高度&#xff0c;里面再加一个空盒子也是这样&#xff0c;这个空盒子就会撑满父容器 <div style"clear:both;"></div> 2.给父容器设置高度&#xff1a; 缺点&#xff1a;得来回设…

容器位置设置

在设置容器位置时&#xff0c;可以使用CSS属性来控制容器的位置。以下是一些常用的CSS属性&#xff1a; position&#xff1a;用于设置元素的定位方式。常见的取值有&#xff1a; static&#xff1a;默认值&#xff0c;元素按照文档流排列&#xff0c;不进行定位。relative&…