使用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 ,其他参数名一样

相关推荐
2601_9620725511 天前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
烂白菜11 天前
智码美形:华为云码道 × UI-UX-Pro-Max 高品质界面智能生成实践
ui·华为云·ux
容器魔方15 天前
Karmada v1.18 版本发布!新增混合云溢出式调度能力
人工智能·云原生·容器·华为云·云计算
DS小龙哥17 天前
基于ESP32设计的智能养蜂监测系统
stm32·单片机·嵌入式硬件·物联网·华为云
江华森18 天前
JumpServer v4.10.16-ce 华为云 ECS 实战部署全记录
华为云
云智慧AIOps社区18 天前
云智慧Cloudwise 亮相华为云 × 霞光社中企私享会,Qreel 重构 AI 短剧出海新范式
人工智能·华为云·ai短剧·短剧创作
码农翻身18 天前
英伟达向左,华为云向右:AI数据中心该走哪条路?
人工智能·华为云
PPIO派欧云18 天前
PPIO亮相华为云创想者大会:以Agentic Cloud加速中国AI走向全球
人工智能·华为云
DS小龙哥19 天前
基于STM32与华为云的智能康养木屋环境监测与控制系统
stm32·嵌入式硬件·华为云
halazi10023 天前
如何在华为云上开通MaaS服务并创建API Key,并在CodeArts Agent中配置使用API Key
华为云·api·tokens