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

相关推荐
xbzb1 天前
华为云弹性文件服务 SFS 与云备份 CBR:一个目录,多台机器共享
华为云·备份·nfs·挂载·sfs·cbr
Linux界最忧郁之人3 天前
华为云ECS&IMS&AS实战|弹性云服务器、私有镜像、弹性伸缩完整实验
linux·运维·服务器·centos·华为云·openstack
yunlaodacom3 天前
做异地灾备,华为云国际站 OBS 跨地域复制该怎么配置?
安全·华为云·云计算
Z21-X3 天前
云原生运维实战笔记:华为云存储类服务全景解析——EVS、OBS、SFS与CBR深度实践
运维·笔记·学习·云原生·华为云
小南家的青蛙4 天前
华为云DCS全形态原生Redis命令兼容性测试方案
redis·华为云·兼容性·兼容性测试·dcs
Z21-X4 天前
云原生运维实战笔记:华为云计算与网络类服务全景解析
运维·笔记·学习·云原生·华为云
終不似少年遊*7 天前
【Skill】为中型研发团队制作的敏捷迭代AI副驾Skill
人工智能·python·华为云·agent·ai编程·skill
熊猫钓鱼>_>8 天前
上架审核常见驳回与隐私合规清单:过审前先自查这 8 条【鸿蒙心迹】
开发语言·前端·华为·华为云·harmonyos·openharmony·ai制作
hyunbar9 天前
华为云 GaussDB(DWS) 和 PG 的谓词下推有何差异
华为云·gaussdb·dws
JoePotter10 天前
从零搭建华为云 EVS 每日自动快照:hcloud + PowerShell + 邮件报告实战
华为云·自动化运维·powershell·evs·koocli·快照备份·mailozaurr