Angular+Python对接AWS上传文件:签名算法错误,需添加AWS4?
解决AWS文件上传签名算法错误(需添加"AWS4"前缀)的问题
看起来你遇到的是**AWS Signature Version 4(V4)**的签名格式不匹配问题——当前你的Python后端是用简单的HMAC-SHA256直接签名,但AWS现在要求上传请求必须使用带"AWS4"前缀的V4签名算法,否则会返回签名无效的错误。
问题核心
AWS S3(以及大部分AWS服务)已经不再支持旧的V2签名,强制要求使用V4签名,它的核心特点是:
- 签名算法标识必须为
AWS4-HMAC-SHA256 - 签名生成需要多步推导:从原始密钥生成AWS4签名密钥,再用该密钥对请求内容(policy)进行签名
- 前端上传表单必须包含额外的V4签名相关字段
步骤1:修改Python后端的签名生成逻辑
替换你当前直接用aws_secret签名的代码,改成符合V4标准的签名流程:
import hmac import hashlib import base64 import json from datetime import datetime # 配置参数 AWS_SECRET_KEY = "你的AWS秘钥" AWS_ACCESS_KEY = AWS_UPLOAD_ACCESS_KEY_ID AWS_REGION = "你的区域(比如us-east-1)" AWS_SERVICE = "s3" DATE_STAMP = datetime.utcnow().strftime("%Y%m%d") DATETIME_STAMP = datetime.utcnow().strftime("%Y%m%dT%H%M%SZ") # 1. 生成AWS4签名密钥 def get_signature_key(key, date_stamp, region_name, service_name): k_date = hmac.new(("AWS4" + key).encode("utf-8"), date_stamp.encode("utf-8"), hashlib.sha256).digest() k_region = hmac.new(k_date, region_name.encode("utf-8"), hashlib.sha256).digest() k_service = hmac.new(k_region, service_name.encode("utf-8"), hashlib.sha256).digest() k_signing = hmac.new(k_service, "aws4_request".encode("utf-8"), hashlib.sha256).digest() return k_signing # 2. 生成并编码Policy(注意你的policy要符合S3要求,包含expiration、conditions等) policy_dict = { "expiration": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"), "conditions": [ {"bucket": "你的存储桶名称"}, ["starts-with", "$key", upload_start_path], # 可添加其他必要条件,比如文件大小限制:["content-length-range", 0, 10485760] ] } policy = base64.b64encode(json.dumps(policy_dict).encode("utf-8")).decode("utf-8") # 3. 生成V4签名 signature_key = get_signature_key(AWS_SECRET_KEY, DATE_STAMP, AWS_REGION, AWS_SERVICE) signature = base64.b64encode(hmac.new(signature_key, policy.encode("utf-8"), hashlib.sha256).digest()).decode("utf-8") # 4. 准备传给前端的完整参数 data = { "policy": policy, "signature": signature, "key": AWS_ACCESS_KEY, "x-amz-algorithm": "AWS4-HMAC-SHA256", "x-amz-date": DATETIME_STAMP, "x-amz-credential": f"{AWS_ACCESS_KEY}/{DATE_STAMP}/{AWS_REGION}/{AWS_SERVICE}/aws4_request", "file_bucket_path": upload_start_path, "venuemenuobject": serializesamplemenu.data, "startpath": upload_start_path }
步骤2:前端上传表单的调整
你的Angular前端在构建上传表单时,必须包含后端传递的所有V4相关字段:
- 确保表单中包含
x-amz-algorithm、x-amz-date、x-amz-credential这三个字段 - 所有字段的名称和值必须和后端生成的完全一致,大小写敏感
关键注意点
- 区域匹配:你的AWS区域(比如
us-east-1)必须和存储桶所在区域完全一致,否则签名会无效 - 时间同步:后端生成签名时的UTC时间必须和请求发送时间接近(误差不能超过15分钟),否则AWS会判定签名过期
- Policy格式:Policy必须是有效的JSON,并且经过base64编码,里面的conditions要符合S3的规则
内容的提问来源于stack exchange,提问作者user9487981
相关产品推荐
相关产品推荐

