使用
最编程
2024-07-12 13:43:12
...
访问管理
腾讯云 COS 服务在使用时需要对请求进行访问管理。通过临时密钥机制,您可以临时授权您的 App 访问您的存储资源,而不会泄露您的永久密钥。密钥的有效期由您指定,过期后自动失效。通常,我们都不建议您把永久密钥放到客户端代码中。本文主要介绍如何在后台快速搭建一个临时密钥服务,通过生成的临时密钥来对上传或者下载请求进行签名,从而保证您数据的安全性。
其中:
用户客户端:即用户手机上的 App
用户服务端:用户的后台服务器,这里用于获取临时密钥,并返回给用户客户端
CAM权限系统:腾讯云访问管理,用于生成 COS 的临时密钥
COS对象存储:腾讯云对象存储,负责存储 App 上传的数据
获取永久密钥
临时密钥需要通过永久密钥才能生成。请登录 腾讯云访问管理控制台 获取,包含:SecretId,SecretKey
搭建临时密钥服务
引入SDK
implementation 'com.qcloud:cos-sts_api:3.1.1';
实现
在nacos中添加配置,也是必须修改参数,其他参数根据自身情况修改。
#对象存储
cos:
enable: true
duration: 1800
bucket: gamioo-1258024122
region: ap-shanghai
secretId: **********************************
secretKey: *********************************
endpoint: https://gamioo-1258024122.cos.ap-shanghai.myqcloud.com
配置初始化:
/**
* 获取联合身份临时访问凭证
*/
public Response reloadCredential() {
TreeMap<String, Object> config = new TreeMap<>();
// 云 api 密钥 SecretId
config.put("secretId", cosProperties.getSecretId());
// 云 api 密钥 SecretKey
config.put("secretKey", cosProperties.getSecretKey());
// 设置域名,可通过此方式设置内网域名
//config.put("host", "sts.internal.tencentcloudapi.com");
// 临时密钥有效时长,单位是秒
config.put("durationSeconds", cosProperties.getDuration());
// 换成你的 bucket
config.put("bucket", cosProperties.getBucket());
// 换成 bucket 所在地区
config.put("region", cosProperties.getRegion());
// 可以通过 allowPrefixes 指定前缀数组, 例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
config.put("allowPrefixes", new String[]{"*"});
// 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
String[] allowActions = new String[]{
//简单上传操作
"name/cos:PutObject",
//表单上传对象
"name/cos:PostObject",
//获取对象
"name/cos:GetBucket",
//分块上传:初始化分块操作
"name/cos:InitiateMultipartUpload",
//分块上传:List 进行中的分块上传
"name/cos:ListMultipartUploads",
//分块上传:List 已上传分块操作
"name/cos:ListParts",
//分块上传:上传分块操作
"name/cos:UploadPart",
//分块上传:完成所有分块上传操作
"name/cos:CompleteMultipartUpload",
//取消分块上传操作
"name/cos:AbortMultipartUpload",
//检索存储桶及其权限
"name/cos:HeadBucket",
//删除对象
"name/cos:DeleteBucket",
};
config.put("allowActions", allowActions);
Response response = null;
try {
response = CosStsClient.getCredential(config);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return response;
}
其中,请求参数说明:
字段 | 类型 | 描述 |
---|---|---|
secretId | String | 云 API 密钥 Id |
secretKey | String | 云 API 密钥 key |
durationSeconds | int | 要申请的临时密钥最长有效时间,单位秒,默认 1800,最大可设置 7200 |
bucket | String | 存储桶名称:bucketName-appid, 如 example-125000000 |
region | String | 存储桶所属地域,如 ap-guangzhou |
allowPrefix | String | 资源的前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用) |
allowActions | String[] | 授予 COS API 权限集合, 如简单上传操作:name/cos:PutObject |
policy | String | 策略:由 allowActions、bucket、region、allowPrefix字段组成的描述授权的具体信息 |
返回值说明
{
"credentials":{
"sessionToken":"mPOLNpDJjVK4Qm22GaUmnWlYzKlpCAja431a1bf3d94fdf541d2be2dcbf82f7baK843Oxi15MH7GZkSGyYVNSNJn9yrtBZxO5_ASQWWL8eR8z_UyHNCxMi6ZMKuwg-hrcLAw-fDPg5LlykM5Y9kiePhd6FBM9UGmVwWCt1b48w3I6vrcFvIM6Cqf_UwbPWiXZYaBNjLMMkVbu869iGvUcTic9X75Bi2Dcmq52GLpUMvie5aFQTw5l_SrKGODOnUIEYEG8Ihnp-l_rdCej2YmcaXEDe8OnP9BuU5SR3lMC93W0cKeyikAHKyeMEG2To2FEQIGCGxogeQfHG03pfQD_8vZUlBOS7qUsK2qzb6B8Uqi7m_7UIyEYZF3b35FQmj9BvMbuJdyXbCoeYeMgk9J1qKDcPtdjAoBPvIo_cCl_PALjbD32mYlpbJoVYJfPC0I3eCT_lI-VMJ4Flb7a81K5bl2A33FUodCBz7MHBvD6140m2iTGNifHz29PJw2QqkvFY08dWiEi3Al0o8qUO5rbxPngt4u7uIZhRmfpiob0eDOLOVFgl5K1TaK7eYowKvv_q-yDBf2qhZSD54iYPcYbIivx4h1Yp7ZriQpaKaGSSZwGYP9cg3LLlEqaAeupvc",
"tmpSecretId":"AKIDiYcPkzj-O6e8k24xCifHoiWeNkZPgHr4l_n7qgj8dbPtsgveL99YCTn-H6cCGu0v",
"tmpSecretKey":"85/Jm3Fu9QoUDEXEOyrZJrCDKjEesFOOhbHQOqOTf18="
},
"expiration":"2023-08-23T04:14:35Z",
"expiredTime":1692764075,
"requestId":"ea06d01d-772a-491e-b736-1d1e55d64d08",
"startTime":1692762275
}
字段 | 类型 | 描述 |
---|---|---|
credentials | String | 临时密钥信息 |
tmpSecretId | String | 临时密钥 Id,可用于计算签名 |
tmpSecretKey | String | 临时密钥 Key,可用于计算签名 |
sessionToken | String | 请求时需要用的 token 字符串,最终请求 COS API 时,需要放在 Header 的 x-cos-security-token 字段 |
startTime | String | 密钥的起始时间,是 UNIX 时间戳 |
expiredTime | String | 密钥的失效时间,是 UNIX 时间戳 |
对返回的值进行二次封装后,得到如下的返回体:
@ApiModel(value = "存储对象临时访问凭证")
public class ResponseDTO {
@ApiModelProperty("存储桶名")
private String bucket;
@ApiModelProperty("地域")
private String region;
@ApiModelProperty("临时证书密钥ID")
private String secretId;
@ApiModelProperty("临时证书密钥Key")
private String secretKey;
@ApiModelProperty("临时令牌")
private String sessionToken;
@ApiModelProperty("临时访问凭证开始时间")
private long startTime;
@ApiModelProperty("临时访问凭证过期时间")
private long expiredTime;
}
在业务层做一层缓存,在失效前从本地读取,失效或者找不到的情况下,才再次去获取临时访问凭证:
@Override
public ResponseDTO getCredential() {
ResponseDTO ret = null;
Response response = null;
String key = RedisConstant.COS_CREDENTIAL;
Object value = redisService.get(key);
if (value != null) {
response = JSON.parseObject(value.toString(), Response.class);
} else {
response = configuration.reloadCredential();
if (response != null) {
long duration = Math.max(0, response.expiredTime - System.currentTimeMillis() / 1000);
String message = JSON.toJSONString(response);
logger.info("key:{},duration:{} seconds,response:{}", key, duration, message);
redisService.setExpire(key, message, duration, TimeUnit.SECONDS);
}
}
if (response != null) {
ret = ResponseDTO.from(configuration.getCosProperties(), response);
}
return ret;
}
最终提供获取临时访问凭证的接口:
/**
* 对象存储(Cloud Object Storage,COS)
*
*/
@RestController
@RequestMapping("/cos")
@Api(tags = "对象存储管理")
public class CosController extends BaseController {
@Resource
private ICosService cosService;
/**
* 获取联合身份临时访问凭证
*
* @return Result
*/
@PreAuth
@GetMapping("/get")
@ApiOperation(value = "获取联合身份临时访问凭证", notes = "获取联合身份临时访问凭证")
public Result<ResponseDTO> get() {
ResponseDTO response = cosService.getCredential();
return Result.data(response);
}
}
推荐阅读
-
如何使用 Illustrator 中的旋转功能自定义锚点位置。
-
Java】--集合框架:使用集合工具类
-
使用 Conda 管理 python 环境指南
-
渗透测试入门学习--使用 python 脚本自动跟踪 csrf_token,实现网站登录界面的暴力破解
-
无线感知会议系列【6】【使用无线信号的行走方向估计
-
Linux第3章 Linux环境下基本开发工具的使用
-
使用 GitLab CI 构建持续集成案例
-
使用内置的 mysql 在 docker 中部署 zendo - 启动 zendo
-
联网]使用网线连接两台计算机的远程桌面-7。其他建议
-
ROS C++:使用 ros::AsyncSpinner 多线程处理 ROS 消息