使用post方式上传文件到华为云obs

默认前端直传到obs是用的put请求方式,在请求体中直接上传binary 二进制数据,但是在uniapp打包安卓和微信小程序时,uni.uploadFile 是post方式并且不支持直接发送binary数据,所以只能对接post使用 multipart/form-data 方式上传

1.后端获取上传时需要的参数

复制代码
package com.mmwzcloud.jszj.module.infra.controller.app.file;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Tag(name = "用户 App - 文件存储")
@RestController
@RequestMapping("/infra/file-obs")
@Validated
@Slf4j
public class ObsController {


    @GetMapping("/post-sign")
    public Map<String,String> postSign(){
        // 允许上传 wx/ 目录,最大 10 MB,30 min 过期
       return sign("HPUA这是我的akPZGOAP", "4BQ2xS72这是我的skVBez74ZLsqhG", "cn-east-3", "jszj-dev",
                "wx/", 10*1024*1024, 30);


        /*return sign("AKIAWSGCTSBWTTAR6UUT", "QnzpVwamshRk2W1ZC1kVnXYcOHQG2W0Q8u0O", "cn-north-4", "obs-test-zh",
                "wx/", 10*1024*1024, 30);*/
    }


    /** 返回前端需要的 5 个字段 */
    public static Map<String,String> sign(String ak,
                                          String sk,
                                          String region,
                                          String bucket,
                                          String dir,
                                          long maxSizeBytes,
                                          int expireMinutes) {

        String host = bucket + ".obs." + region + ".myhuaweicloud.com";

        // 1. 构造 policy
        String policy = Base64.getEncoder().encodeToString(
                ("{\"expiration\":\""
                        + Instant.now().plus(expireMinutes, ChronoUnit.MINUTES).toString()
                        + "\",\"conditions\":[{\"bucket\":\"" + bucket + "\"},"
                        + "[\"starts-with\",\"$key\",\"" + dir + "\"],"
                        + "[\"content-length-range\",0," + maxSizeBytes + "]]}")
                        .getBytes(StandardCharsets.UTF_8));

        // 2. 计算 signature
        String signature = signPolicy(sk, policy);

        Map<String,String> map = new HashMap<>();
        map.put("host","https://" + host);
        map.put("ak",ak);
        map.put("policy",policy);
        map.put("signature",signature);
        map.put("dir",dir);
        return map;
    }

    /** 用 AWS SigV4 计算 policy 签名 */
    private static String signPolicy(String sk, String policyBase64) {
        try {
            // 华为云 OBS 对 PostObject 采用 AWS2 旧签名(HMAC-SHA1)
            javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
            mac.init(new javax.crypto.spec.SecretKeySpec(sk.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
            byte[] hash = mac.doFinal(policyBase64.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(hash);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

2.获取上传参数

复制代码
curl --location --request GET 'http://192.168.1.166:38080/app-api/infra/file-obs/post-sign' \
--header 'tenant-id: 1' \
--header 'terminal: 31' \
--header 'Authorization: Bearer 8f8106c7f63d4c02a73ba0954e3b6a9f'

3.调用obs上传文件

复制代码
curl --location --request POST 'https://jszj-dev.obs.cn-east-3.myhuaweicloud.com/' \
--form 'AccessKeyId="HPUAACHPJ15SJKPZGOAP"' \
--form 'policy="eyJleHBpcmF0aW9uIjoiMjAyNi0wMS0xN1QwMjozNjo1Ni42ODAxOTI2MDBaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoianN6ai1kZXYifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInd4LyJdLFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjBdXX0="' \
--form 'signature="odUJrx2m+uBaJTYQCduLzkwexzc="' \
--form 'key="wx/9-23_00306666666.jpg"' \
--form 'file=@"E:\\图\\9-23_0030.jpg"'

其中 的 AccessKeyId 就是上个接口的 ak ,其他参数名一样

相关推荐
开开心心_Every4 天前
发票批量打印工具支持双面预览页面方向设置
游戏·微信·pdf·华为云·excel·语音识别·googlecloud
TracyCoder1234 天前
解读华为云Redis Proxy集群规格:架构、规格与带宽性能
redis·架构·华为云
江湖有缘4 天前
华为云之基于鲲鹏服务器部署打砖块小游戏全流程
服务器·华为云·github
开开心心_Every6 天前
家常菜谱软件推荐:分类齐全无广告步骤详细
linux·运维·服务器·华为od·edge·pdf·华为云
九河云7 天前
数字韧性时代,华为云CBR为业务连续性注入“免疫基因”
大数据·人工智能·安全·机器学习·华为云
zhangfeng11338 天前
华为云ModelArts「大模型部署 & 微调」指南
人工智能·华为云
智慧化智能化数字化方案8 天前
向华为学习——解读华为云安全白皮书 2025【附全文阅读】
学习·安全·华为云·华为云安全白皮书
嘴贱欠吻!9 天前
Kuikly搭建OpenHarmony教程02:使用华为云真机运行项目
华为云
Goway_Hui9 天前
【开源鸿蒙跨平台开发--KuiklyUI--02】华为云真机部署实战指南
华为·开源·华为云·harmonyos·kuikly
qq_3863226910 天前
华为云Stack 解决方案技术
华为云