具体流程:首先我们需要将aliyun-oss-spring-boot-starter需要的签名数据配置在项目的配置文件里
其中签名数据包括四个部分:access-key、secret-key、endpoint、bucket,如下配置:
# 引入oss依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>aliyun-oss-spring-boot-starter</artifactId>
</dependency>
# 配置参数
alibaba:
cloud:
access-key: LTAI5tLjeLxxxxxxx
secret-key: loUIZ566Zxxxxxxxx
oss:
endpoint: oss-cn-shanghai.aliyuncs.com
bucket: xxxxxxxx
当我们进行文件上传时,前端先向后获取上传的防伪签名,然后带着防伪签名和文件到OSS进行文件上传,这个过程阿里云OSS会验证签名是否正确,正确则进行文件上传。
为OSS对象存储配置专门的子账户,使用子账户的AccessKey和Security来生成访问签名,开通子账户地址阿里云开通OSS子账户 ,开通完子账户之后,我们还需要为该子账户添加特定的权限,比如管理OSS权限等。
参考代码:
@Autowired
private OSS ossClient;
@Value("${alibaba.cloud.oss.endpoint}")
private String endpoint;
@Value("${alibaba.cloud.oss.bucket}")
private String bucket;
@Value("${alibaba.cloud.access-key}")
private String accessId;
@GetMapping("/policy")
public R policy() throws ServletException, IOException {
// String bucket = "bucket-name"; // 请填写您的 bucketname 。
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
// String callbackUrl = "http://88.88.88.88:8888";
// String dir = "user-dir-prefix/"; // 用户上传文件时指定的前缀。
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
Map<String, String> respMap = new HashMap<>();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
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, date);
// 生成post请求代理
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
// 将String类型的签名转换成字节数组
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
// 将字节数组转换成
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
// 生成签名
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", date);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
} finally {
ossClient.shutdown();
}
return R.ok().put("data",respMap);
}
当前端从后端拿到签名数据后,前端的上传组件就可以通过绑定oss的backet地域节点为上传地址,同时携带上传数据和签名进行上传。