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

相关推荐
咕噜企业分发小米1 天前
阿里云与华为云基因测序数据同步安全性对比?
阿里云·华为云·云计算
咕噜企业分发小米1 天前
阿里云与华为云基因测序数据同步延迟对比?
阿里云·华为云·云计算
洲洲不是州州1 天前
APP与华为云和设备端的通信
华为云·手机apk·云端通信
咕噜企业分发小米1 天前
阿里云与华为云基因测序数据同步的日志格式是什么?
阿里云·华为云·云计算
咕噜企业分发小米1 天前
阿里云和华为云基因测序数据同步的审计日志如何查看?
阿里云·oracle·华为云
咕噜企业分发小米2 天前
阿里云与华为云基因测序数据分析中如何优化成本?
阿里云·华为云·云计算
咕噜企业分发小米2 天前
阿里云与华为云基因测序数据分析如何实现数据协同?
阿里云·华为云·云计算
咕噜企业分发小米2 天前
阿里云与华为云基因测序数据分析中如何实现数据共享?
阿里云·华为云·云计算
@YDWLCloud3 天前
华为云国际版 vs 阿里云国际版:东南亚市场选型指南
大数据·服务器·阿里云·华为云·云计算