介绍

阿里云上传 OSS 有两种方式,一种是普通上传,一种是客户端直传。

  1. 普通上传,就是需要先将文件上传到服务端,然后调用接口将文件上传到阿里云。

当然这种方案经常出现不合理的使用方式,即客户端充当服务端的角色,在本地直接通过AK/SK,调用阿里云接口上传文件。

不建议客户端直接这样做,一旦AK/SK泄露,存在很大的安全隐患,有可能被盗用。

  1. 客户端直传

通过服务器下发上传令牌,客户端通过使用临时令牌,直接上传到阿里云 OSS。

这种是最佳方案,不仅安全,而且不占用服务器带宽,传输速度快。

接下来,本文围绕这种方案介绍如何实现,并以 Python 语言为例,其他语言的实现类似,可以从参考文档下载相应的 Demo

配置权限

创建用户并生成 AK,SK

这里建议专门为 API 调用创建一个用户,然后生成AK,SK,记录好AK,SK以便后续使用,并授予权限。

点击权限管理,添加 AliyunSTSAssumeRoleAccess (调用STS服务AssumeRole接口的权限)

在这里插入图片描述

创建角色

创建一个角色,创建成功后,记录角色的 ARN,后面代码中会用到,为了方便演示,这里将角色命名为:ramossuploadonly

在这里插入图片描述

添加权限策略

导航栏找到权限策略,点击创建,点击“脚本编辑”, 在文本框中输入以下内容,将 <Bucket名称> 替换成自己的 Bucket 名称,然后点击保存,

例如,bucket 名称为 oss-upload-demo,则 Resource 填写为 "acs:oss:*:*:oss-upload-demo/*"

{"Version": "1","Statement": [{"Effect": "Allow","Action": "oss:PutObject","Resource": "acs:oss:*:*:<Bucket名称>/*"}]
}

点击保存,例如可将名称命名为 oss-upload-policy

为角色授权

回到刚刚添加的角色 ramossuploadonly,点击新增授权,从权限策略中搜索刚刚添加的 oss-upload-policy,点击确认新增授权。

这样权限就配置完成了。

创建 bucket

打开对象存储 OSS,点击创建 Bucket,在弹窗中输入 bucket 名称

在这里插入图片描述

需要注意的是,需要记住这里的选择地域,后面代码中会用到,OSS上传需要指定地域,本文中选择北京

编写代码

安装依赖

主要用到以下的依赖包, requirements.txt 文件内容如下

Flask
alibabacloud-credentials
alibabacloud-tea-openapi
alibabacloud-sts20150401
oss2

使用 pip 安装:

pip install -r requirements.txt

创建 main.py 文件

基于官方 demo,主要修改以下内容:

access_key_id = '###AK###'
access_key_secret = '###SK###'
role_arn_for_oss_upload = '###acs:ram::19920XXX5721:role/roleoss###'# 自定义会话名称
role_session_name = 'yourRoleSessionName'# 替换为实际的bucket名称、region_id、host
bucket = ' oss-upload-demo'
region_id = 'cn-beijing'
host = 'http://oss-upload-demo.oss-cn-beijing.aliyuncs.com'

这里 access_key_id, access_key_secret 为最开始创建用户后,拿到的 AK,SK 的值,替换成相应的内容。

role_arn_for_oss_upload 为创建的 RAM 角色ramossuploadonly时,拿到的 ARN,可以打开角色详情找到ARN。

bucket 为自己创建的 bucket 名称,本示例中为 oss-upload-demo
region_id 为 bucket 所在的区域,本示例中为 cn-beijing
host 为 bucket 的访问地址,本示例中为 http://oss-upload-demo.oss-cn-beijing.aliyuncs.com, 根据不同的区域,访问地址不同,可以通过OSS地域和访问域名, 找到 bucket 对应地域的访问域名,选择外网 Endpoint

在这里插入图片描述

需要注意的是,官方 demo 中,需要全搜索 cn-hangzhou, 替换掉 bucket 地域的 ID

完整内容如下:

from flask import Flask, render_template, jsonify, request
from alibabacloud_tea_openapi.models import Config
from alibabacloud_sts20150401.client import Client as Sts20150401Client
from alibabacloud_sts20150401 import models as sts_20150401_models
import os
import json
import base64
import hmac
import datetime
import time
import hashlibimport oss2app = Flask(__name__)# 配置环境变量 OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, OSS_STS_ROLE_ARN
# access_key_id = os.environ.get('OSS_ACCESS_KEY_ID')
# access_key_secret = os.environ.get('OSS_ACCESS_KEY_SECRET')
# role_arn_for_oss_upload = os.environ.get('OSS_STS_ROLE_ARN')access_key_id = '###AK###'
access_key_secret = '###SK###'
role_arn_for_oss_upload = '###acs:ram::19920XXX5721:role/roleoss###'# 自定义会话名称
role_session_name = 'yourRoleSessionName'# 替换为实际的bucket名称、region_id、host
bucket = ' oss-upload-demo'
region_id = 'cn-beijing'
host = 'http://oss-upload-demo.oss-cn-beijing.aliyuncs.com'# 指定过期时间,单位为秒
expire_time =  1000# 指定上传到OSS的文件前缀
upload_dir = 'dir'def hmacsha256(key, data):"""计算HMAC-SHA256哈希值的函数:param key: 用于计算哈希的密钥,字节类型:param data: 要进行哈希计算的数据,字符串类型:return: 计算得到的HMAC-SHA256哈希值,字节类型"""try:mac = hmac.new(key, data.encode(), hashlib.sha256)hmacBytes = mac.digest()return hmacBytesexcept Exception as e:raise RuntimeError(f"Failed to calculate HMAC-SHA256 due to {e}")@app.route("/")
def hello_world():return render_template('index.html')@app.route('/get_post_signature_for_oss_upload', methods=['GET'])
def generate_upload_params():# 初始化配置,直接传递凭据config = Config(region_id=region_id,access_key_id=access_key_id,access_key_secret=access_key_secret)# 创建 STS 客户端并获取临时凭证sts_client = Sts20150401Client(config=config)assume_role_request = sts_20150401_models.AssumeRoleRequest(role_arn=role_arn_for_oss_upload,role_session_name=role_session_name)response = sts_client.assume_role(assume_role_request)token_data = response.body.credentials.to_map()# 使用 STS 返回的临时凭据temp_access_key_id = token_data['AccessKeyId']temp_access_key_secret = token_data['AccessKeySecret']security_token = token_data['SecurityToken']now = int(time.time())# 将时间戳转换为datetime对象dt_obj = datetime.datetime.utcfromtimestamp(now)# 在当前时间增加3小时,设置为请求的过期时间dt_obj_plus_3h = dt_obj + datetime.timedelta(hours=3)# 请求时间dt_obj_1 = dt_obj.strftime('%Y%m%dT%H%M%S') + 'Z'# 请求日期dt_obj_2 = dt_obj.strftime('%Y%m%d')# 请求过期时间expiration_time = dt_obj_plus_3h.strftime('%Y-%m-%dT%H:%M:%S.000Z')# 定义回调参数Base64编码函数。def encode_callback(callback_params):cb_str = json.dumps(callback_params).strip()return oss2.compat.to_string(base64.b64encode(oss2.compat.to_bytes(cb_str)))# 构建回调配置并 Base64 编码callback_config = {"callbackUrl": "http://x.x.x.x/images/callback",  # 替换为您的回调服务器地址"callbackBody": "bucket=${bucket}&object=${object}&etag=${etag}&size=${size}","callbackBodyType": "application/x-www-form-urlencoded"}encoded_callback = encode_callback(callback_config)# 构建 Policy 并生成签名policy = {"expiration": expiration_time,"conditions": [["eq", "$success_action_status", "200"],{"x-oss-signature-version": "OSS4-HMAC-SHA256"},{"x-oss-credential": f"{temp_access_key_id}/{dt_obj_2}/{region_id}/oss/aliyun_v4_request"},{"x-oss-security-token": security_token},{"x-oss-date": dt_obj_1},]}policy_str = json.dumps(policy).strip()# 步骤2:构造待签名字符串(StringToSign)stringToSign = base64.b64encode(policy_str.encode()).decode()# 步骤3:计算SigningKeydateKey = hmacsha256(("aliyun_v4" + temp_access_key_secret).encode(), dt_obj_2)dateRegionKey = hmacsha256(dateKey, region_id)dateRegionServiceKey = hmacsha256(dateRegionKey, "oss")signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request")# 步骤4:计算Signatureresult = hmacsha256(signingKey, stringToSign)signature = result.hex()# 组织返回数据response_data = {'policy': stringToSign,  # 表单域'x_oss_signature_version': "OSS4-HMAC-SHA256",  # 指定签名的版本和算法,固定值为OSS4-HMAC-SHA256'x_oss_credential': f"{temp_access_key_id}/{dt_obj_2}/cn-beijing/oss/aliyun_v4_request",  # 指明派生密钥的参数集'x_oss_date': dt_obj_1,  # 请求的时间'signature': signature,  # 签名认证描述信息'host': host,'dir': upload_dir,'security_token': security_token,  # 安全令牌#'callback': encoded_callback   # 返回 Base64 编码的回调配置}return jsonify(response_data)if __name__ == "__main__":app.run(host="127.0.0.1", port=8000)  # 如果需要监听其他地址如0.0.0.0,需要您自行在服务端添加认证机制

这里下载好官方给出的 Demo

创建 html 页面

在项目中创建目录 templates,然后创建一个 index.html 文件,内容为:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>服务端生成签名上传文件到OSS</title>
</head>
<body>
<div class="container"><form><div class="mb-3"><label for="file" class="form-label">选择文件:</label><input type="file" class="form-control" id="file" name="file" required /></div><button type="submit" class="btn btn-primary">上传</button></form><div id="callback-info" class="mt-3" style="display: none;"><h4>回调信息:</h4><pre id="callback-content"></pre></div>
</div><script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {const form = document.querySelector("form");const fileInput = document.querySelector("#file");const callbackInfo = document.querySelector("#callback-info");const callbackContent = document.querySelector("#callback-content");form.addEventListener("submit", (event) => {event.preventDefault();const file = fileInput.files[0];if (!file) {alert('请选择一个文件再上传。');return;}const filename = file.name;fetch("/get_post_signature_for_oss_upload", { method: "GET" }).then((response) => {if (!response.ok) {throw new Error("获取签名失败");}return response.json();}).then((data) => {let formData = new FormData();formData.append("success_action_status", "200");formData.append("policy", data.policy);formData.append("x-oss-signature", data.signature);formData.append("x-oss-signature-version", "OSS4-HMAC-SHA256");formData.append("x-oss-credential", data.x_oss_credential);formData.append("x-oss-date", data.x_oss_date);formData.append("key", data.dir + file.name); // 文件名formData.append("x-oss-security-token", data.security_token);formData.append("callback", data.callback);  // 添加回调参数formData.append("file", file); // file 必须为最后一个表单域return fetch(data.host, {method: "POST",body: formData});}).then((response) => {if (response.ok) {console.log("上传成功");alert("文件已上传");return response.json();  // 解析回调信息} else {console.log("上传失败", response);alert("上传失败,请稍后再试");}}).then((callbackData) => {if (callbackData) {callbackContent.textContent = JSON.stringify(callbackData, null, 2);callbackInfo.style.display = "block";}}).catch((error) => {console.error("发生错误:", error);});});
});
</script>
</body>
</html>

代码写好后,运行服务。

python server.py

这将启动服务后,打开浏览器访问 http://127.0.0.1:8000, 将展示一个简单的上传页面,进行测试

在这里插入图片描述

首先选择文件,然后点击上传,这将先获取临时上传令牌,然后使用令牌,直接将文件上传到阿里云OSS

参考资料

  • 服务端签名直传
  • OSS地域和访问域名

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

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

相关文章

on-policy和offpolicy算法

一句话总结On-policy&#xff08;同策略&#xff09;&#xff1a;边学边用&#xff0c;用当前策略生成的数据更新当前策略。例子&#xff1a;演员自己演完一场戏后&#xff0c;根据观众反馈改进演技。Off-policy&#xff08;异策略&#xff09;&#xff1a;学用分离&#xff0c…

CA-IS3082W 隔离485 收发器芯片可能存在硬件BUG

RT&#xff0c;这个RS485 隔离收发器芯片基本上不可用。本来要买CA-IS3082WX&#xff0c;不小心在某宝买到了没有X 的CA-IS3082W。立创上说没有X 的版本已经停产&#xff0c;连对应的数据手册都找不到&#xff0c;全换成WX 了。 这类半双工485 收发器芯片电路一般都直接把DE 和…

dockerfile 笔记

# 设置JAVA版本 FROM openjdk:20-ea-17-jdk MAINTAINER aaa # 指定存储卷, 任何向/tmp写入的信息都不会记录到容器存储层 VOLUME /tmp # 拷贝运行JAR包 ARG JAR_FILE COPY app.jar /app.jar RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo "Asia/…

高德开放平台携手阿里云,面向开发者推出地图服务产品MCP Server

高德开放平台携手阿里云&#xff0c;面向开发者推出地图服务产品MCP Server&#xff0c;通过技术能力与生态资源的深度协同&#xff0c;助力开发者高效构建标准化地图服务&#xff0c;加速智能化场景落地。 高德开放平台携手阿里云&#xff0c;面向开发者推出MCP Server技术融合…

【论文阅读】AdaptThink: Reasoning Models Can Learn When to Think

AdaptThink: Reasoning Models Can Learn When to Think3 Motivation3.1 理论基础3.2 NoThinking在简单问题中的优势3.3 动机总结4. AdaptThink4.1 约束优化目标数学建模基本定义原始优化问题惩罚项转换归一化处理策略梯度实现优势函数定义PPO风格损失函数4.2 重要性采样策略问…

Redis高可用集群一主从复制概述

一、环境概述在分布式集群系统中为了解决服务单点故障问题&#xff0c;通常会把数据复制出多个副本部署到不同的机器中&#xff0c;满足故障恢复和负载均衡等需求。Redis也是如此&#xff0c;它为我们提供了复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可…

Java 树形结构、层级结构数据构建

目录前言一、树状结构数据库存储二、工具类三、测试四、自定义树节点返回类型&#xff08;只保留部分字段&#xff09;1. 新增 TreeNodeDTO 类2.修改TreeUtil 类3.测试4.输出前言 有时候&#xff0c;开发过程中我们会遇到一些树状层级结构。 比如&#xff0c;公司部门组织架构…

求解线性规划模型最优解

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 既然选择了远方&#xff0c;当不负青春…

达梦国产数据库安装

打开ISO 、文件点击运行接受选择安装路径数据初始化 新数据库要创建数据库实例 选择一般用途数据库位置 选择所以系统用户&#xff0c;设置初始密码创建示例库可以选可以不选查找最近添加文件登录

互斥锁与同步锁

1. 锁的本质&#xff1a;解决并发问题的基石在多线程/多进程环境中&#xff0c;临界区&#xff08;Critical Section&#xff09; 是访问共享资源的代码段。锁的核心目标是确保互斥访问——任意时刻仅有一个执行单元能进入临界区。// 典型临界区示例 pthread_mutex_lock(&m…

高密度PCB板生产厂商深度解析

在电子制造领域&#xff0c;高密度PCB&#xff08;印制电路板&#xff09;作为核心基础元件&#xff0c;其技术精度与生产稳定性直接影响终端产品性能。本文精选五家具备核心技术优势的国内厂商&#xff0c;通过实地调研与行业数据验证&#xff0c;为读者呈现真实可信的供应商选…

力扣 hot100 Day44

98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树 //自…

【基础架构】——软件系统复杂度的来源(低成本、安全、规模)

目录 一、软件系统复杂度的来源之低成本二、软件系统复杂度的来源之安全2.1、功能安全2.2、架构安全2.3、规模2.3.1、功能越来越多,导致系统复杂度指数级上升2.3.2、数据越来越多,系统复杂度发生质变本文来源:极客时间vip课程笔记 一、软件系统复杂度的来源之低成本 当我们设…

机器学习 YOLOv5手绘电路图识别 手绘电路图自动转换为仿真软件(如LT Spice)可用的原理图,避免人工重绘

以下是对《手绘电路图识别》论文的核心解读&#xff0c;结合技术方案、实验数据和创新点进行结构化总结&#xff1a;研究目标 解决痛点&#xff1a;将手绘电路图自动转换为仿真软件&#xff08;如LT Spice&#xff09;可用的原理图&#xff0c;避免人工重绘。 关键挑战&#xf…

一般的非线性规划求解(非凸函数)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一个裂缝都是为透出光而努力&#x…

CTFHub————Web{信息泄露[Git泄露(Stash、Index)]}

Web 信息泄露 Git泄露 Stash 首先&#xff0c;我们先读题&#xff0c;由题可知我们可以用BugScanTeam或GitHack完成该题那么我们先开题&#xff0c; 好吧&#xff0c;他问我们flag在哪里&#xff0c;我怎么知道fag在哪里。 先打开GitHack 使用 py GitHack.py http://challenge-…

缺乏实际里程碑管控项目进度,如何设定关键节点

要通过实际里程碑管控项目进度&#xff0c;核心措施包括&#xff1a;设定可量化的关键节点、明确交付标准与责任人、同步风险与资源计划、基于阶段目标拆解任务、建立节点验证与复盘机制。例如&#xff0c;设定可量化的关键节点能让团队清晰理解“何时完成了什么”并及时调整方…

XML E4X:深入解析与高效应用

XML E4X:深入解析与高效应用 引言 XML(可扩展标记语言)作为一种数据交换格式,广泛应用于互联网数据传输、配置文件、数据存储等领域。E4X 是一种扩展 XML 的编程接口,允许开发者以编程方式直接访问和处理 XML 数据。本文将深入探讨 XML E4X 的概念、特点、应用场景以及高…

uniapp---入门、基本配置了解

目录 uniapp 新建项目 uniapp全局配置 组件 1、内置组件 2、扩展 组件 uni-ui 3、第三方组件库 uview-ui 秋云-ucharts (插件市场 ) scss语法(了解) vue2语法&#xff08;熟悉&#xff09; uniapp 官方文档&#xff1a;uni-app官网 uni-app 是一个使用 Vue.js 开发所…

springboot 好处

思考1&#xff0c;快速启动&#xff0c;简化配置。自动配置&#xff0c;内置tomcat&#xff0c;无需部署war文件&#xff0c;快速创建独立应用2&#xff0c;提高开发效率&#xff0c;热部署3&#xff0c;微服务生态4&#xff0c;云原生&#xff0c;Docker K8sSpring Boot 的主要…