1.创建RAM用户
可以通过STS服务给其他用户颁发一个临时访问凭证。该用户可使用临时访问凭证在规定时间内访问您的OSS资源。临时访问凭证无需透露您的长期密钥,使您的OSS资源访问更加安全;
创建用户,保存访问密钥(AccessKey ID 和 AccessKey Secret);
2.为RAM用户授予请求AssumeRole的权限
已创建RAM用户右侧对应的添加权限;
3.创建用于获取临时访问凭证的角色
以 RamOssTest 为名,进行说明;
4.为角色授予上传文件的权限
-
创建上传文件的自定义权限策略 -以 RamTestPolicy为名,进行说明;
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject" ], "Resource": [ "acs:oss:*:*:examplebucket/exampledir", "acs:oss:*:*:examplebucket/exampledir/*" ] } ] }
-
为RAM角色 RamOssTest 授予自定义权限策略;
在添加权限页面下的自定义策略页签,选择已创建的自定义权限策略 RamTestPolicy;
5.获取临时访问凭证
// 通过STS服务生成临时访问凭证
const OSS = require('ali-oss');
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高;
// 强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户;
const sts = new OSS.STS({
accessKeyId: 'accessKeyId',
accessKeySecret: 'accessKeySecret'
});
// 参考以下示例代码,具体参数说明详见下列链接:
// roleArn: 格式为acs:ram::$accountID:role/$roleName;
// policy: 为步骤4填写的权限策略;
// sessionName: 用户自定义参数。此参数用来区分不同的令牌,可用于用户级别的访问审计;
// https://help.aliyun.com/document_detail/28763.htm
// sts.assumeRole('roleArn', 'policy', 'expiration', 'sessionName').then((result) => {
// console.log(result);
// }).catch((err) => {
// console.log(err);
// });
sts.assumeRole('acs:ram::123456789012****:role/adminrole', {
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:PutObject"
],
"Resource": [
"acs:oss:*:*:examplebucket/exampledir",
"acs:oss:*:*:examplebucket/exampledir/*"
]
}
]
}, '3600', 'adminrole').then((result) => {
// SecretCode - example:
// {
// SecurityToken: 'SecurityToken',
// AccessKeyId: 'STS.XXXXXXX',
// AccessKeySecret: 'AccessKeySecret',
// Expiration: '2020-03-12T03:16:01Z'
// }
console.log(result.credentials);
}).catch((err) => {
console.log(err);
});
// 在客户端使用临时访问凭证初始化OSSClient,用于临时授权访问OSS资源
const axios = require("axios");
const OSS = require("ali-oss");
// 在客户端使用临时访问凭证初始化OSS客户端,用于临时授权访问OSS资源。
const getToken = async () => {
// 设置客户端请求访问凭证的地址。
await axios.get("https:/xxx/sts").then((token) => {
const client = new OSS({
// 以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou
region: 'yourRegion',
accessKeyId: token.AccessKeyId,
accessKeySecret: token.AccessKeySecret,
stsToken: token.SecurityToken,
// 填写Bucket名称,例如examplebucket
bucket: "examplebucket",
// 刷新临时访问凭证
refreshSTSToken: async () => {
const refreshToken = await axios.get("https://xxx/sts");
return {
accessKeyId: refreshToken.AccessKeyId,
accessKeySecret: refreshToken.AccessKeySecret,
stsToken: refreshToken.SecurityToken,
};
},
});
});
};
6.使用临时访问凭证上传文件至OSS
// 使用阿里云 OSS-SDK 上传
const OSS = require('ali-oss');
// 填写步骤5获取的临时访问密钥(AccessKey ID、AccessKey Secret 和 SecurityToken)
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'STS.XXXXXXX',
accessKeySecret: 'AccessKeySecret',
bucket: 'examplebucket',
stsToken: 'SecurityToken'
});
const data = document.getElementById("file").files[0];
const result = await client.put(
"application/x-oss-forbid-overwrite.png",
data
// {headers}
);
// 使用 axios、wx.uploadFile 等工具上传
// https://help.aliyun.com/document_detail/92883.html
import { Base64 } from 'js-base64';
const policyText = {
// 设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件
expiration: `${new Date(timestamp).toISOString()}`,
conditions: [
// 限制上传大小
["content-length-range", 0, 1024 * 1024 * 1024],
],
};
const policy = Base64.encode(JSON.stringify(policyText));
// 填写步骤5获取的临时访问密钥(AccessKey Secret)
const Signature = crypto.enc.Base64.stringify(crypto.HmacSHA1(policy, "accessKeySecret"));
// 服务端签名直传并设置上传回调,该参数可选
// https://help.aliyun.com/document_detail/31927.html?spm=a2c4g.11186623.6.1388.24906e28BwjPD3
const callback = {
callbackUrl: 'https://tuanzi.test.com/callback',
callbackBody:
"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
callbackBodyType: "application/x-www-form-urlencoded",
}
const CallbackUrls = Buffer.from(JSON.stringify(callback)).toString("base64")
// 填写步骤5获取的临时访问密钥(AccessKey ID 和 SecurityToken)
function fileCreate (file) {
const uploadData = new FormData();
uploadData.append("OSSAccessKeyId", 'STS.XXXXXXX');
uploadData.append("key", 'application/${filename}');
uploadData.append("policy", policy);
uploadData.append("success_action_status", 200);
uploadData.append("name", file.name);
// 使用STS签名时必传
uploadData.append("x-oss-security-token", "securityToken");
uploadData.append("Signature", Signature);
// uploadData.append("callback", CallbackUrls);
uploadData.append("file", file);
return uploadData;
}
const file = document.getElementById("file").files[0];
const uploadData = fileCreate(file);
axios({
url: 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com',
method: 'post',
data: uploadData,
headers: { 'Content-Type': 'multipart/form-data' }
}).then(r => console.log(r));
7.使用签名URL进行临时授权
可以将生成的签名URL提供给访客进行临时访问;
生成签名URL时,您可以通过指定URL的过期时间来限制访客的访问时长。签名URL的默认过期时间为3600秒,最大值为32400秒;
const OSS = require('ali-oss');
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高;
// 强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户;
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'accessKeyId',
accessKeySecret: 'accessKeySecret',
bucket: 'examplebucket',
});
// 用于生成对应签名URL来上传和下载文件
// const url = client.signatureUrl('pathname/2Q2tTXZ5JRHb72.png');
// 生成带图片处理参数的签名URL
const url = client.signatureUrl('pathname/2Q2tTXZ5JRHb72.png', {
// 设置过期时间,默认值为1800秒。
expires: 3600,
// 设置图片处理参数。
process: 'image/resize,w_200'
});
// http://examplebucket.region.aliyuncs.com/pathname/filename.png?OSSAccessKeyId=OSSAccessKeyId&Expires=1647075144&Signature=Signature
console.log(url);