服务端签名后直传见上一篇博客:【Vue+java+阿里云oss】服务端签名后直传,文件下载(私有bucket),详细步骤及前后端代码(一)
经过上篇博客的操作,我们应该可以将文件成功上传到阿里云oss中了。
文件下载阿里云文档:https://help.aliyun.com/document_detail/64052.html
下载私有bucket的文件,需要用到STS服务,获取到临时访问权限。
1.STS服务
如何开启sts服务的官方文档:https://help.aliyun.com/document_detail/100624.html
子用户上篇博客已经创建过了,现在只需要新创建一个角色,给角色添加上STS权限即可,【文档中选择脚本配置,可以更加精细化,但是可能有点麻烦】
2. 获取临时访问凭证
写一个接口,用于获取临时访问凭证。代码如下:
@RequestMapping("/xxx/xxx")
public AjaxResult sts() {
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
String roleSessionName = "SessionTest";
// 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。
// 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。
Map<String, String> respMap = null;
try {
// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
String regionId = "cn-xxxxxx";
// 添加endpoint。
DefaultProfile.addEndpoint(regionId, "Sts", endpoint, "sts.aliyun.com");
// 构造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, accessId, accessKeySecret);
// 构造client。
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(null); // 如果policy为空,则用户将获得该角色下所有权限。
request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。
final AssumeRoleResponse response = client.getAcsResponse(request);
respMap = new HashMap<>();
respMap.put("region", "oss-" + regionId);
respMap.put("bucket", bucket);
respMap.put("accessKeyId", response.getCredentials().getAccessKeyId());
respMap.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
respMap.put("stsToken", response.getCredentials().getSecurityToken());
respMap.put("RequestId", response.getRequestId());
respMap.put("expiration", response.getCredentials().getExpiration());
return AjaxResult.success().put("data", respMap);
} catch (ClientException e) {
respMap = new HashMap<>();
respMap.put("errorCode", e.getErrCode());
respMap.put("errorMessage", e.getErrMsg());
respMap.put("requestId", e.getRequestId());
return AjaxResult.error().put("data", respMap);
}
}
3.前端Vue方法
前端只需要先获取凭证,然后再用a标签的形式下载即可
/**下载按钮操作 */
handleDownLoad(row) {
getSts().then((response) => {
console.log("response:", response);
const OSS = require("ali-oss");
const client = new OSS({
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: response.data.region,
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: response.data.accessKeyId,
accessKeySecret: response.data.accessKeySecret,
// 从STS服务获取的安全令牌(SecurityToken)。
stsToken: response.data.stsToken,
// 填写Bucket名称。
bucket: response.data.bucket,
});
// 配置响应头实现通过URL访问时自动下载文件,并设置下载后的文件名。
const filename = "examplefile.pptx"; // 自定义下载后的文件名。
const responseHead = {
"content-disposition": `attachment; filename=${encodeURIComponent(
filename
)}`,
};
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
const url = client.signatureUrl(row.url, { responseHead });
console.log("url=" + url);
const a = document.createElement("a");
a.setAttribute("target", "_blank");
a.setAttribute("href", url);
a.click();
});
},
这个自定义下载后的文件名,是没有用的,点击下载按钮会自动下载,下载的文件名和bucket中保存的文件名一样,暂时不想改了。
getSts()方法就是请求后端STS服务的方法,返回值中包括region、accessKeyId等内容【见上面后端Java代码】
// 获取阿里云下载sts临时凭证
export function getSts() {
return request({
url: '/xxx/xxx',
method: 'get',
})
}
注意:我的下载按钮是在表格每一条记录后面加的,表格记录中有文件在bucket中的路径即row.url的值是【Object完整路径。Object完整路径中不能包含Bucket名称。】