服務端實現阿里云OSS直傳

介紹

阿里云上傳 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 的主要…