aksk前端签名实现

需求:

页面和后台使用aksk进行签名校验,普通JSON参数签名没问题,但使用formData上传文件时签名总是无法通过后台校验

关键点:

1、浏览器在传递formData格式数据时会自动随机boundary,这样页面无法在请求发起前拿到随机boundary,造成前后台计算入参不一致

2、formData格式的数据是否可以直接用来计算其hash

解决方案:

1、针对随机boundary问题,通过手动指定解决

2、因为随机boundary问题,暂未找到直接对formData格式数据签名方式,构造其结构转二进制实现

关键代码:

1、将formData内容拆成两部分计算计算其二进制数据

  const fields = {fileName: fileInfo.fileName,chunk: currentChunk + 1,chunks: totalChunks,uploadId: fileInfo.uploadId,fileType: fileType.value}const files = {file: chunk}const boundary = '----MyCustomBoundaryABC'

2、拼接二进制数据

async function buildMultipartFormData(fields, files, boundary) {const CRLF = '\r\n'const encoder = new TextEncoder()const chunks = []const pushText = (text) => chunks.push(encoder.encode(text))// 普通字段for (const [name, value] of Object.entries(fields)) {pushText(`--${boundary}${CRLF}`)pushText(`Content-Disposition: form-data; name="${name}"${CRLF}${CRLF}`)pushText(`${value}${CRLF}`)}// 文件字段for (const [name, file] of Object.entries(files)) {const filename = file.name || 'blob'const mimeType = file.type || 'application/octet-stream'pushText(`--${boundary}${CRLF}`)pushText(`Content-Disposition: form-data; name="${name}"; filename="${filename}"${CRLF}`)pushText(`Content-Type: ${mimeType}${CRLF}${CRLF}`)const fileBuffer = new Uint8Array(await file.arrayBuffer())chunks.push(fileBuffer)pushText(CRLF)}// 结尾pushText(`--${boundary}--${CRLF}`)// 合并所有 Uint8Array 块const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0)const body = new Uint8Array(totalLength)let offset = 0for (const chunk of chunks) {body.set(chunk, offset)offset += chunk.length}return body
}

3、使用二进制数据进行签名

  buildMultipartFormData(fields, files, boundary).then(async (bodyBinary) => {// 查看构造的内容(可选)const auth = await createAuth(bodyBinary)// 发送请求fetch('/cos/upload', {method: 'POST',headers: {'Content-Type': `multipart/form-data; boundary=${boundary}`,'Authorization': auth},body: bodyBinary})})

4、签名实现

import { SHA256, HmacSHA256, enc } from 'crypto-js';
function useAuth() {function hmacWithSHA256(message, secretKey) {// 计算 HMAC-SHA256const hmac = HmacSHA256(message, secretKey);// 返回十六进制字符串(小写)return hmac.toString(enc.Hex);}function generateRandomString(length = 16) {const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';let result = '';for (let i = 0; i < length; i++) {result += chars.charAt(Math.floor(Math.random() * chars.length));}return result;}async function hash256(data) {const str = typeof data === 'string' ? data : JSON.stringify(data);return SHA256(str).toString();}async function createAuth(bodyRaw) {const appid = 'app_demo'const access = 'ak_demo'const sk = 'sk_demo'const expiretime = Math.floor(Date.now() / 1000) + 10000const nonce = generateRandomString()let hashBody;if (bodyRaw instanceof Uint8Array) {hashBody = await calculateBinaryHash(bodyRaw)} else {hashBody = await hash256(typeof bodyRaw === 'string' ? bodyRaw : JSON.stringify(bodyRaw))}const signature = hmacWithSHA256(hashBody + expiretime + nonce, sk)const res = `appid=${appid},access=${access},signature=${signature},nonce=${nonce},expiretime=${expiretime}`return res}const calculateBinaryHash = async (binaryData: Uint8Array | ArrayBuffer): Promise<string> => {// 浏览器环境if (typeof window !== 'undefined' && crypto.subtle) {const hashBuffer = await crypto.subtle.digest('SHA-256', binaryData);const hashArray = Array.from(new Uint8Array(hashBuffer));return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');}};return {createAuth}
}export { useAuth }

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90657.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90657.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于物联网的智能体重秤设计与实现

标题:基于物联网的智能体重秤设计与实现内容:1.摘要 随着物联网技术的飞速发展&#xff0c;智能设备在人们日常生活中的应用越来越广泛。本研究的目的是设计并实现一款基于物联网的智能体重秤&#xff0c;以满足人们对健康数据实时监测和管理的需求。方法上&#xff0c;采用高精…

安全领域的 AI 采用:主要用例和需避免的错误

作者&#xff1a;来自 Elastic Elastic Security Team 安全领域的 AI 采用&#xff1a;主要用例和需避免的错误 人工智能&#xff08;artificial intelligence - AI&#xff09;在安全领域的广泛应用呈现出一种矛盾。一方面&#xff0c;它帮助安全专家大规模应对高级威胁&…

Element-Plus-全局自动引入图标组件,无需每次import

效果图配置如下1、核心代码修改main.js/ts//main.js // 全局注册图标组件 import * as ElementPlusIconsVue from element-plus/icons-vue for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component) } app.use(ElementPlusIconsVu…

日历插件-FullCalendar的详细使用

一、介绍FullCalendar 是一个功能强大、高度可定制的 JavaScript 日历组件&#xff0c;用于在网页中显示和管理日历事件。它支持多种视图&#xff08;月、周、日等&#xff09;&#xff0c;可以轻松集成各种框架&#xff0c;并提供丰富的事件处理功能。二、实操案例具体代码如下…

【A题解题思路】2025APMCM亚太杯中文赛A题解题思路+可运行代码参考(无偿分享)

注&#xff1a;该内容由“数模加油站”原创&#xff0c;无偿分享&#xff0c;可以领取参考但不要利用该内容倒卖&#xff0c;谢谢&#xff01;A 题 农业灌溉系统优化问题1思路框架&#xff1a;1.1 研究背景与问题意义土壤湿度是农业生产中影响作物根系水分供应的关键环境指标。…

【JAVA】面向对象三大特性之继承

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、继承的概念和使用细则1.1 继承的基本使用和含义1.2 关于子类访问父类成员的问题1.3 super关键的引出1.4 super调用父类当中指定的构造方法1.5 关于super和th…

基于深度学习的自动调制识别网络(持续更新)

基于卷积神经网络架构 CNN 参考文献 T.J. O’Shea, J. Corgan, T.C. Clancy, Convolutional radio modulation recognition networks, in: Proc. Int. Conf. Eng. Appl. Neural Netw., Springer, 2016, pp. 213–226. MCNet 参考文献 T. Huynh-The, C.-H. Hua, Q.-V. Pha…

Java进阶---并发编程

一.线程复习1.什么是线程&#xff0c;进程进程是操作系统分配资源的基本单位线程是进程中的一个执行单元(一个独立执行的任务)&#xff0c;是cpu执行的最小单元2.Java中如何创建线程1.继承Thread类&#xff0c;重写run()&#xff0c;直接创建子类的对象2.类实现Runnable接口&am…

小车循迹功能的实现(第六天)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-削好皮的Pineapple! &#x1f468;‍&#x1f4bb; hello 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 削好皮的Pineapple! 原创 &#x1f468;‍&#x1f4…

C++ auto与 for循环

一、数组 #include <iostream> #include <vector> using namespace std; int main() {int vec[6] {1,2,3};for (auto num : vec) { /* num 是 int */ cout << "Hello, world!" << num <<endl;}return 0; }二、STL容器与迭代器 for 循…

【RK3568+PG2L50H开发板实验例程】FPGA部分 | ROM、RAM、FIFO 的使用

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 1.实验简介 实验目的&#xff1a; 掌握紫光平台的 RAM、ROM、FIFO IP 的使用 实验环境&#xff1a; Window11 PDS2022…

力扣-21.合并两个有序链表

题目链接 21.合并两个有序链表 class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode p1 list1;ListNode p2 list2;ListNode p new ListNode(0);ListNode cur p;while (p1 ! null && p2 ! null) {if (p1.val > p2.val) …

MoE混合专家模型:千亿参数的高效推理引擎与架构革命

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 从稀疏激活到多模态协同的智能计算范式 &#x1f9e9; 一、核心思想与…

【论文笔记】BlockGaussian:巧妙解决大规模场景重建中的伪影问题

论文地址&#xff1a;https://arxiv.org/pdf/2504.09048 大规模场景的重建方法不仅仅对于高空航拍数据有效&#xff0c;而且对于地面大中场景也有增强效果&#xff0c;故专门来学习一下这一方向的知识。感谢作者大佬们的great work。 Abstract 三维高斯泼溅&#xff08;3DGS…

网络众筹项目数据库(2014-2024.11)

1727网络众筹项目数据库&#xff08;2014-2024.11&#xff09;数据简介作为新兴互联网融资模式&#xff0c;众筹已成为越来越多创业者和中小企业获取资金的渠道&#xff0c;但众筹项目一直面临融资成功率低的困难&#xff0c;成功融资的项目在许多平台上占比不足五成。而目前对…

k8s新增jupyter服务

k8s新增服务 常用命令 kubectl apply -f xxxxxx.yaml # 部署资源&#xff0c;顺序&#xff1a;namespace -> pvc -> deployment -> servicekubectl create namespace jupyter # 创建namespacekubectl get namespaces # 查看nskubectl get pods -n jupyter # 查看p…

结构化数据、非结构化数据区别

一、核心定义结构化数据&#xff1a;指具有固定格式、可直接用二维表&#xff08;如数据库表&#xff09;表示的数据&#xff0c;其字段&#xff08;列&#xff09;定义明确&#xff0c;数据之间的关系清晰。例如&#xff1a;Excel 表格中的数据、关系型数据库&#xff08;MySQ…

Linux修炼:基础指令

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》、《Linux修炼&#xff1a;终端…

【Linux网络】深入理解HTTP/HTTPS协议:原理、实现与加密机制全面解析

协议是通信双方必须遵守的规则&#xff0c;确保数据能够正确传输和解析&#xff0c;它规定了数据格式、传输顺序、错误处理等细节。应用层的协议一般都是我们自己进行定义的&#xff0c;但是有很多程序员前辈已经写出来了很哇塞的协议&#xff0c;我们直接进行学习和使用即可HT…

浅尝 Spring AI【使用超级简单~】

一直想要体验下 Spring AI&#xff0c;最近自己的一个工具有这个需求&#xff0c;所以这里准备使用下。其实使用起来超级简单。 1.IDEA 新建 Spring项目 1&#xff09;这里可以根据自己的喜好选择 项目名、jdk版本等 2&#xff09;这里选择 在ai中选择 openAI 即可。然后我另…