阿里云 OSS 客户端直传 Policy 模式使用

一、OSS Policy 模式

Post policy 是阿里推出的一种安全的文件上传方式,在传统的方式一般都是客户端将文件上传至服务端,再由服务端将文件上传至具体的文件系统比如阿里云的OSS,这种方式不仅增加了我们服务器的带宽,而且效率也不怎么高,为此阿里提出的policy 模式,是由服务端进行签名,客户端拿到签名后的 policy 直连阿里云的OSS进行上传文件,并且阿里也提供了上传后的回调方案。

流程如下图所示:
在这里插入图片描述
用户要上传一个文件到OSS,而且希望将上传的结果返回给应用服务器时,需要设置一个回调函数,将请求告知应用服务器。用户上传完文件后,不会直接得到返回结果,而是先通知应用服务器,再把结果转达给用户。

具体的就不做讲解了,毕竟是阿里中国的,不了解的大家可以去看下官网的介绍,下面看下使用的过程,

二、获取 Bucket 及 AccessKey ID 和 AccessKey Secret

在操作之前确保已经开通了OSS功能。

创建 Bucket

首先进入OSS控制台:
在这里插入图片描述
点击Bucket:
在这里插入图片描述
创建一个
在这里插入图片描述
在这里插入图片描述
主要填写bucket名称和地域,其他看具体情况选择。填写后点击下面的确认按钮。下面自动跳转的页面就可以看到bucket 的域名了。
在这里插入图片描述
下面我们上传和下载都需要使用这个域名,这里还需要配制bucket的跨域允许,因为我们是客户端直连肯定存在跨域问题。

点击 bucket列表,进入刚才创建的bucket
在这里插入图片描述
点击权限管理:
在这里插入图片描述
下面就有一个跨域设置了。
在这里插入图片描述
点击设置,创建一个规则:
在这里插入图片描述
主要设置来源和请求方式即可,来源不做限制就填写*即可。
在这里插入图片描述

创建RAM用户

下面还需创建一个RAM用户,回到最初的OSS控制台页面,右边常用入口由访问控制RAM,点击它进入RAM控制台。
在这里插入图片描述

点击用户,开始创建用户:

在这里插入图片描述
在这里插入图片描述
主要填写下面标出来的。
在这里插入图片描述
点击确认后,会出现该用户的AccessKey IDAccessKey Secret,者这两个需要记下来,后面需要使用。在这里插入图片描述
在这里插入图片描述
下面需要给该用户分配OSS的权限,点击该页面的左边菜单的用户,出现用户列表,列表中添加权限的操作。
在这里插入图片描述
在这里插入图片描述

到此在阿里云上的操作基本就完成了,注意上面的bucket 的名称和域名,以及AccessKey IDAccessKey Secret 后面都要使用。

三、测试是否可以上传文件

在上传创建好bucket和RAM用户后,我们就可以新建一个SpringBoot项目测试下,是否可以上传文件。

新建SpringBoot项目,在pom中引入阿里云oss的依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>aliyun-oss-spring-boot-starter</artifactId>
</dependency>

在配制文件中配制 access-keysecret-key 以及 endpoint,修改application.yml文件:

server:
  port: 8080

alibaba:
  cloud:
    access-key: LTAI5tJxf****MCQVK*****
    secret-key: Urc3oALFm*****lF6sAzRMwEF*****
    oss:
      endpoint: oss-cn-shanghai.aliyuncs.com

access-keysecret-key就是上面创建RAM用户后得到的,endpoint是创建Bucket是选的地区,在Bucket页面的概述就可以看到。
在这里插入图片描述
下面编写测试接口:

@Slf4j
@RestController
@RequestMapping("/file")
public class UpdateController {
    @Resource
    OSS ossClient;

    @GetMapping("/upload")
    public String file() throws FileNotFoundException {
        String bucketName = "bxcosstest"; // Bucket的名称
        String localFile = "C:/Users/Administrator/Desktop/photo.jpg";
        String fileKeyName = "photo2.jpg"; // 上传至阿里云的名称,可以使用 / 附带文件夹
        InputStream inputStream = new FileInputStream(localFile);
        PutObjectResult putObjectResult = ossClient.putObject(bucketName, fileKeyName, inputStream);
        log.info(putObjectResult.getETag());
        return "success";
    }
}

下面在浏览器调用接口http://localhost:8080/file/upload
在这里插入图片描述
已经打印出Etag,看下阿里云的bucket的控制台:
在这里插入图片描述
已经上传成功了,下面我们就可以使用下Policy 模式进行文件的上传了。

四、获取服务端认证的 Policy

先修改下我们的配制文件,将Bucket的名称配制在配制文件中:

alibaba:
  cloud:
    access-key: LTAI5tJxf****MCQVK*****
    secret-key: Urc3oALFm*****lF6sAzRMwEF*****
    oss:
      endpoint: oss-cn-shanghai.aliyuncs.com
      bucketName: bxcosstest

创建获取Policy 的接口:

@Slf4j
@CrossOrigin
@RestController
public class PolicyController {
    @Resource
    OSS ossClient;

    @Value("${alibaba.cloud.access-key}")
    private String accessId;

    @Value("${alibaba.cloud.secret-key}")
    private String accessKey;

    @Value("${alibaba.cloud.oss.endpoint}")
    private String endpoint;

    @Value("${alibaba.cloud.oss.bucketName}")
    private String bucketName;


    @GetMapping("/getPolicy")
    public JSONObject getPolicy() throws UnsupportedEncodingException, JSONException {
        // host的格式为 bucketname.endpoint
        String host = StringFormatter.concat("https://", bucketName, ".", endpoint).getValue();
        // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
        // String callbackUrl = "http://88.88.88.88:8888";
        // 每一天产生一个文件夹
        String dir = LocalDate.now().toString() + "/"; // 用户上传文件时指定的前缀,如果是 / 则自动检测为文件夹。

        JSONObject jsonObject = new JSONObject();

        long expireTime = 100;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000; //过期时间 100 秒
        Date expiration = new Date(expireEndTime);
        // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
        String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes("utf-8");
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = ossClient.calculatePostSignature(postPolicy);

        jsonObject.put("OSSAccessKeyId", accessId);
        jsonObject.put("policy", encodedPolicy);
        jsonObject.put("signature", postSignature);
        jsonObject.put("dir", dir);
        jsonObject.put("host", host);
        jsonObject.put("expire", String.valueOf(expireEndTime / 1000));
        return jsonObject;
    }
}    

启动服务,调用接口:http://localhost:8080/getPolicy

在这里插入图片描述

下面使用拿到的参数使用PostMan上传文件测试:
在这里插入图片描述

去阿里云中查看文件:
在这里插入图片描述
在这里插入图片描述

五、前端使用认证后的 Policy 上传文件

测试上穿的程序:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>文件上传</title>
</head>
<body>
<div>
    <input type="file" id="file">

    <button id="upload">上传文件</button>
</div>
</body>

<script src="js/jquery-1.10.2.min.js"></script>
<script>
    var filename = '';
    var file = null;
    $("#file").change(function () {
        let f = document.getElementById("file").files[0];
        if (typeof f != "undefined") {
            let src = window.URL.createObjectURL(f);
            if (src === null || src === '') {
                return;
            }
            filename = f.name;
            file = f;
        }
    });

    $("#upload").click(function () {
        let data = getPolicy();
        var formData = new FormData();
        formData.append("OSSAccessKeyId", data.OSSAccessKeyId);
        formData.append("signature", data.signature);
        formData.append("policy", data.policy);
        formData.append("key", data.dir + (new Date()).valueOf() + filename);//注意顺序,file要在key的后面。不然会返回找不到key 的错误
        formData.append("file", file);
        formData.append("success_action_status", 200);
        $.ajax({
            url: data.host,
            type: "POST",
            data: formData,
            contentType: false,
            processData: false,
            success: function (data, status, response) {
                if (status === 'success') {
                    alert("上传成功!")
                }
            },
            error: function (e) {
                alert("上传失败!");
                console.log("失败", e);
            }
        });
    });

    function getPolicy() {
        var restultData = null;
        $.ajax({
            url: "http://localhost:8080/getPolicy",
            type: "GET",
            async: false,
            success: function (data, status, request) {
                if (status === 'success') {
                    restultData = data;
                }
            },
            error: function (e) {
                console.log("失败", e);
            }
        });
        return restultData;
    }


</script>
</html>

测试
在这里插入图片描述
查看阿里云Bucket控制页面:
在这里插入图片描述

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毕超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值