使用STS临时访问凭证通过客户端直连OSS对象存储服务器

目录

1、导论

2、客户端直传

3、创建RAM用户以及RAM角色

4、如何实现客户端直传

4.1、跨域访问

4.2、安全授权

5、代码示例

5.1、后端代码实例

5.2、客户端代码实例 


1、导论

        最近在做项目的过程中使用到了阿里云OSS来存储客户端上传的文件,方法是直接将客户端上传的文件发送到业务服务器,再通过业务服务器将文件上传到OSS对象存储服务器当中。

        起初觉得是什么问题的,但是在使用的过程中会发现上传文件的速度很慢,显然是受到业务服务器宽带的限制。为了解决这个问题我翻看了OSS的官方文档,在里面学到了不经过业务服务器的转发,而是直接让客户端和OSS服务器进行连接直接上传。下面为大家讲解一下在客户端直连OSS的操作过程。

2、客户端直传

        客户端直传是指客户端直接上传文件到对象存储OSS。相对于服务端代理上传,客户端直传避免了业务服务器中转文件,提高了上传速度,节省了服务器资源。

        在典型的服务端和客户端架构下,常见的文件上传方式是服务端代理上传:客户端将文件上传到业务服务器,然后业务服务器将文件上传到OSS。在这个过程中,一份数据需要在网络上传输两次,会造成网络资源的浪费,增加服务端的资源开销。为了解决这一问题,可以在客户端直连OSS来完成文件上传,无需经过业务服务器中转。

总结:

服务器代理上传和客户端直传相比,有三个缺点:

  1. 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
  2. 扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
  3. 费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,那么将能省下几台应用服务器。

3、创建RAM用户以及RAM角色

        在RAM访问控制工作台中,在左侧导航栏中选择“用户”,创建用户并勾选OpenAPI调用访问

        创建完毕后为该用户添加授权,搜索oss以及sts将管理oss的权限以及sts权限授权给创建的用户,此时使用该用户的AccessKeyId以及AccessKeySecret凭证就可以向STS获取临时凭证。

再通过左侧导航栏的角色,创建一个普通用户,并授权oss权限。

最后查看角色详情,可以看到角色的ARN,即 roleArn。

4、如何实现客户端直传

        实现客户端直传需要解决以下两个大问题:

4.1、跨域访问

        如果客户端是Web端或小程序,需要解决跨域访问被限制的问题。浏览器以及小程序容器出于安全考虑,通常都会限制跨域访问,这一限制也会限制客户端代码直连OSS。

4.2、安全授权

        而实现客户端直传的另外一个大问题就是安全授权问题。

        客户端要想实现上传,必须要得到AccessKeyId以及AccessKeySecret凭证,通过凭证才能向OSS发起请求。而如果直接将这两个身份凭证放到前端,用户很容易就能够通过F12获取到,一旦被获取,用户可以用来做任何事情,例如向OSS中存储大量垃圾数据。

         为了解决这一问题,OSS提供了STS临时访问凭证。在服务端使用STS SDK获取STS临时访问凭证,然后在客户端使用STS临时凭证和OSS SDK直接上传文件。客户端能重复使用服务端生成的STS临时访问凭证生成签名。

  1. 客户端向业务服务器请求临时访问凭证。

  2. 业务服务器使用STS SDK调用AssumeRole接口,获取临时访问凭证。

  3. STS生成并返回临时访问凭证给业务服务器。

  4. 业务服务器返回临时访问凭证给客户端。

  5. 客户端使用OSS SDK通过该临时访问凭证上传文件到OSS。

  6. OSS返回成功响应给客户端。

5、代码示例

5.1、后端代码实例

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
public class StsServiceSample {public static void main(String[] args) { // STS服务接入点,例如sts.cn-hangzhou.aliyuncs.com。 String endpoint = "sts.cn-hangzhou.aliyuncs.com";String accessKeyId = "OSS_ACCESS_KEY_ID";String accessKeySecret = "OSS_ACCESS_KEY_SECRET";String roleArn = "OSS_STS_ROLE_ARN";// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。        String roleSessionName = "yourRoleSessionName";// 如果policy为空,则临时访问凭证将获得角色拥有的所有权限。      String policy = "{\n" +"    \"Version\": \"1\", \n" +"    \"Statement\": [\n" +"        {\n" +"            \"Action\": [\n" +"                \"oss:PutObject\"\n" +"            ], \n" +"            \"Resource\": [\n" +"                \"acs:oss:*:*:*\" \n" +"            ], \n" +"            \"Effect\": \"Allow\"\n" +"        }\n" +"    ]\n" +"}";// 临时访问凭证的有效时间,单位为秒。最小值为900,最大值以当前角色设定的最大会话时间为准。当前角色最大会话时间取值范围为3600秒~43200秒,默认值为3600秒。// 在上传大文件或者其他较耗时的使用场景中,建议合理设置临时访问凭证的有效时间,确保在完成目标任务前无需反复调用STS服务以获取临时访问凭证。Long durationSeconds = 3600L;try {// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。String regionId = "";// 添加endpoint。适用于Java SDK 3.12.0及以上版本。DefaultProfile.addEndpoint(regionId, "Sts", endpoint);// 添加endpoint。适用于Java SDK 3.12.0以下版本。// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);// 构造default profile。IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);// 构造client。DefaultAcsClient client = new DefaultAcsClient(profile);final AssumeRoleRequest request = new AssumeRoleRequest();// 适用于Java SDK 3.12.0及以上版本。request.setSysMethod(MethodType.POST);// 适用于Java SDK 3.12.0以下版本。//request.setMethod(MethodType.POST);request.setRoleArn(roleArn);request.setRoleSessionName(roleSessionName);request.setPolicy(policy); request.setDurationSeconds(durationSeconds); final AssumeRoleResponse response = client.getAcsResponse(request);System.out.println("Expiration: " + response.getCredentials().getExpiration());System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());System.out.println("Security Token: " + response.getCredentials().getSecurityToken());System.out.println("RequestId: " + response.getRequestId());} catch (ClientException e) {System.out.println("Failed:");System.out.println("Error code: " + e.getErrCode());System.out.println("Error message: " + e.getErrMsg());System.out.println("RequestId: " + e.getRequestId());}}
}

需要注意的是:

1、durationSeconds的最大取值是角色最大会话时间,如需调整最大实现需要前往RAM控制台进行修改。

 

2、由于频繁地调用STS服务会引起限流,因此需要对STS临时凭证做缓存处理,并在有效期前刷新。例如可以使用Redis进行缓存操作。

        将应用服务器获取到的STS临时访问凭证credentials传递给前端,前端通过解析credentials即可获得相应的凭证,从而通过凭证创建OSSClient并上传文件。

5.2、客户端代码实例 

// 从cookie中获取sts
let stsParameter = Base64.decode(getCookie("sts"));
// 如果cookie中没有,则向后端发起请求获取sts
if (stsParameter.length === 0) {await that.$axios.get("/user/sts").then(res => {stsParameter = res.data.datasetCookie("sts", Base64.encode(JSON.stringify(stsParameter)), 60 * 60 * 2)})
} else {stsParameter = JSON.parse(stsParameter)
}
let cli = client(stsParameter);export function client(data) {return new OSS({region: data.region,accessKeyId: data.credentials.accessKeyId,accessKeySecret:  data.credentials.accessKeySecret,bucket: data.bucketName,stsToken: data.credentials.securityToken,refreshSTSToken: async () => {const refreshToken = await axios.get("http://localhost:8890/api/user/sts");return {accessKeyId: refreshToken.credentials.accessKeyId,accessKeySecret: refreshToken.credentials.AccessKeySecret,stsToken: refreshToken.credentials.securityToken,};},})
}

前端通过解析credentials即可获得相应的凭证,从而通过凭证创建OSSClient并获得上传文件的权限。

【博主推荐】 

【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类_java concurrent哪些类-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136777947?spm=1001.2014.3001.5502【网络原理】TCP 协议中比较重要的一些特性(三)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136597348?spm=1001.2014.3001.5502【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列_单例模式懒汉和饿汉 java s1==s2-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136688859?spm=1001.2014.3001.5502

如果觉得作者写的不错,求给博主一个点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个点赞支持一下,你们的支持是我更新的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/20813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Keras深度学习框架实战(3):EfficientNet实现stanford dog分类

1、通过EfficientNet进行微调以实现图像分类概述 通过EfficientNet进行微调以实现图像分类,是一个使用EfficientNet作为预训练模型,并通过微调(fine-tuning)来适应特定图像分类任务的过程。一下是对相关重要术语的解释。 Effici…

Flutter-自定义可展开文本控件

Flutter 在移动开发中,常常需要处理一些长文本显示的场景,如何优雅地展示这些文本并允许用户展开和收起是一个常见的需求。在本文中,我将分享如何使用Flutter实现一个可展开和收起的文本控件。 效果 我们将实现一个可展开和收起的文本控件…

yolov10模块

yolov10模块 1 C2f2 C2fCIB2.1 CIB2.2 RepVGGDW 3 PSA4 SCDown5 v10Detect 论文代码:https://github.com/THU-MIG/yolov10 论文链接:https://arxiv.org/abs/2405.14458 Conv是Conv2dBNSiLU PW是Pointwise Convolution(逐点卷积) DW是Depthwise Convolut…

【SQL学习进阶】从入门到高级应用【企业真题】

文章目录 第一题第二题第三题第四题第五题第六题第七题第八题第九题MySQL行转列使用case whengroup by完成 第十题 🌈你好呀!我是 山顶风景独好 💕欢迎来到我的博客,很高兴能够在这里和您见面! 💕希望您在这…

疫情物资捐赠和分配系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,机构管理,用户管理,发放管理,物资管理 前台账户功能包括:系统首页,个人中心,物资论坛,公告信息…

STM32作业设计

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

彻底卸载Windows Defender

概述 卸载Windows Defender的方法有很多,如修改注册表、组策略,执行脚本等等,这些方法操作过于繁琐和复杂,不适合小白,今天带来一款强大的卸载工具,只需要以管理员身份运行该软件即可,不用其他操…

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》Chapter 6插图

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 Chapter 6插图

Stable Diffusion详细教程

目录 🐋引言 🐋Stable Diffusion基本概念 🦈潜在扩散模型 🦈图像生成原理 🐋Stable Diffusion安装部署 🦈环境要求 🦈安装步骤 🐋Stable Diffusion阶段 🦈准备阶…

PHP 页面报错Warning</b>: Cannot modify header information - headers already sent by

先给出解决方案再解释,如果急着用就不用看解释了。 解决方案一:保存php文件编码为utf-8无BOM码,具体操作可以用notepad等编辑器完成,把 sesstion_start() 放在文档所有输出(包括html标签和php的输出语句,具…

ch4网络层---计算机网络期末复习(持续更新中)

网络层概述 将分组从发送方主机传送到接收方主机 发送方将运输层数据段封装成分组 接收方将分组解封装后将数据段递交给运输层网络层协议存在于每台主机和路由器上 路由器检查所有经过它的IP分组的分组头 注意路由器只有3层(网络层、链路层、物理层) 网络层提供的服务 一…

Java筑基-集合[Set、Map、List、Stack、Queue]

这里写目录标题 一、Collection接口结构图二、Set集合1、常用方法 三、List集合1、List集合常用方法2、代码案例 四、Stack集合1、方法2、代码展示 五、Queue集合1、常用的方法2、代码展示 六、Map集合1、基本概念2、常用方法3、代码展示 一、Collection接口结构图 二、Set集合…

小熊家务帮day8-day9 客户管理模块2 (用户定位,地址簿,实名认证,银行卡信息上传等功能)

客户管理模块 0.用户定位功能0.1 需求0.2 接口分析0.3 接口开发Controller层开发Service层开发 1.我的地址簿功能1.1 需求1.2 数据库设计1.3 新增地址簿1.3.1 接口设计1.3.2 接口开发Controller层开发Service层开发测试功能 1.4 地址簿查询1.4.1 接口设计1.4.2 接口开发Control…

Caliburn.Micro框架学习笔记——多页面处理案例

在聊这个之前,我们先来看一个静态类 在 Caliburn.Micro 中,ViewLocator 是一个用于查找和关联视图与视图模型的静态类。默认情况下,它根据约定(命名约定或其他规则)自动找到与视图模型相对应的视图。然而,…

C语言 | Leetcode C语言题解之第126题单词接龙II

题目: 题解: char** list; int** back; int* backSize;// DFS uses backtrack information to construct results void dfs(char*** res, int* rSize, int** rCSizes, int* ans, int last, int retlevel) {int i ans[last];if (i 0) {res[*rSize] (c…

实验报告 GUI窗体和标签

实验目的: 理解AWT和Swing工具包 掌握窗体和组件的创建方法。 实验要求: (1)掌握创建GUI窗体的操作 (2)掌握标签的使用 (3)代码应遵循Java编程规范,包含恰当的注释…

网上蛋糕售卖店管理系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,店员管理,用户管理,商品管理,基础数据管理 前台账户功能包括:系统首页,个人中心,公告信息,商品…

2024医美如何做抖音医美抖音号,本地团购、短视频直播双ip爆品引流,实操落地课

课程下载:https://download.csdn.net/download/m0_66047725/89307619 更多资源下载:关注我。 课程内容: 01-0-序.mp4 02-01-账号定位.mp4 03-02-误区.mp4 04-03-五件套.mp4 05-04-文案怎么来.mp4 06-05-对标怎么弄.mp4 07-06-人设怎…

进程与线程(四)

进程与线程(四) 基于System V IPC对象的进程间通信机制SystemV IPC引入查看Linux系统中IPC工具的方式查看所有IPC工具命令:ipcs 查看指定的IPC工具key值获取方法:ftok()函数 消息队列消息队列的特征:消息队列的操作打开…

处理多对一的映射关系

1、级联属性赋值 Emp实体类中设置Dept 属性并生成get、set方法,生成toString方法,但是构造方法不必包含此属性 在EmpMapper.xml文件中: <resultMap id="empAndDeptResultMapOne" type="Emp"><id property="eid" column="eid…