OSS如何限制上传文件类型及大小

您所在的位置:网站首页 下载文档如何调整格式和大小 OSS如何限制上传文件类型及大小

OSS如何限制上传文件类型及大小

2024-07-13 13:55| 来源: 网络整理| 查看: 265

服务端生成Post签名和PostPolicy

对于需要限制上传文件属性的场景,您可以在服务端生成PostObject所需的Post签名、PostPolicy等信息,然后客户端可以凭借这些信息,在一定的限制下不依赖OSS SDK直接上传文件。您可以借助服务端生成的PostPolicy限制客户端上传的文件,例如限制文件大小、文件类型。此方案适用于通过HTML表单上传的方式上传文件。需要注意的是,此方案不支持基于分片上传大文件、基于分片断点续传的场景。更多信息,请参见PostObject。

示例代码

服务端示例代码

服务端生成Post签名和Post Policy等信息的代码示例如下:

import os from hashlib import sha1 as sha import json import base64 import hmac import datetime import time # 配置环境变量OSS_ACCESS_KEY_ID。 access_key_id = os.environ.get('OSS_ACCESS_KEY_ID') # 配置环境变量OSS_ACCESS_KEY_SECRET。 access_key_secret = os.environ.get('OSS_ACCESS_KEY_SECRET') # 将替换为Bucket名称。 bucket = '' # host的格式为bucketname.endpoint。将替换为Bucket名称。将替换为OSS Endpoint,例如oss-cn-hangzhou.aliyuncs.com。 host = 'https://.' # 指定上传到OSS的文件前缀。 upload_dir = 'user-dir-prefix/' # 指定过期时间,单位为秒。 expire_time = 3600 def generate_expiration(seconds): """ 通过指定有效的时长(秒)生成过期时间。 :param seconds: 有效时长(秒)。 :return: ISO8601 时间字符串,如:"2014-12-01T12:00:00.000Z"。 """ now = int(time.time()) expiration_time = now + seconds gmt = datetime.datetime.utcfromtimestamp(expiration_time).isoformat() gmt += 'Z' return gmt def generate_signature(access_key_secret, expiration, conditions, policy_extra_props=None): """ 生成签名字符串Signature。 :param access_key_secret: 有权限访问目标Bucket的AccessKeySecret。 :param expiration: 签名过期时间,按照ISO8601标准表示,并需要使用UTC时间,格式为yyyy-MM-ddTHH:mm:ssZ。示例值:"2014-12-01T12:00:00.000Z"。 :param conditions: 策略条件,用于限制上传表单时允许设置的值。 :param policy_extra_props: 额外的policy参数,后续如果policy新增参数支持,可以在通过dict传入额外的参数。 :return: signature,签名字符串。 """ policy_dict = { 'expiration': expiration, 'conditions': conditions } if policy_extra_props is not None: policy_dict.update(policy_extra_props) policy = json.dumps(policy_dict).strip() policy_encode = base64.b64encode(policy.encode()) h = hmac.new(access_key_secret.encode(), policy_encode, sha) sign_result = base64.b64encode(h.digest()).strip() return sign_result.decode() def generate_upload_params(): policy = { # 有效期。 "expiration": generate_expiration(expire_time), # 约束条件。 "conditions": [ # 未指定success_action_redirect时,上传成功后的返回状态码,默认为 204。 ["eq", "$success_action_status", "200"], # 表单域的值必须以指定前缀开始。例如指定key的值以user/user1开始,则可以写为["starts-with", "$key", "user/user1"]。 ["starts-with", "$key", upload_dir], # 限制上传Object的最小和最大允许大小,单位为字节。 ["content-length-range", 1, 1000000], # 限制上传的文件为指定的图片类型 ["in", "$content-type", ["image/jpg", "image/png"]] ] } signature = generate_signature(access_key_secret, policy.get('expiration'), policy.get('conditions')) response = { 'policy': base64.b64encode(json.dumps(policy).encode('utf-8')).decode(), 'ossAccessKeyId': access_key_id, 'signature': signature, 'host': host, 'dir': upload_dir # 可以在这里再自行追加其他参数 } return json.dumps(response)

客户端示例代码

Web端使用Post签名和Post Policy等信息上传文件到OSS的代码示例如下:

const form = document.querySelector('form'); const fileInput = document.querySelector('#file'); form.addEventListener('submit', (event) => { event.preventDefault(); let file = fileInput.files[0]; let filename = fileInput.files[0].name; fetch('/get_post_signature_for_oss_upload', { method: 'GET' }) .then(response => response.json()) .then(data => { const formData = new FormData(); formData.append('name',filename); formData.append('policy', data.policy); formData.append('OSSAccessKeyId', data.ossAccessKeyId); formData.append('success_action_status', '200'); formData.append('signature', data.signature); formData.append('key', data.dir + filename); // file必须为最后一个表单域,除file以外的其他表单域无顺序要求。 formData.append('file', file); fetch(data.host, { method: 'POST', body: formData },).then((res) => { console.log(res); alert('文件已上传'); }); }) .catch(error => { console.log('Error occurred while getting OSS upload parameters:', error); }); });服务端生成签名URL

生成签名URL时,不支持指定content-length-range,因此不适用于限制上传文件大小的场景。对于要限制上传文件类型的场景,您可以在服务端生成签名URL时,强制指定content-type,客户端凭借签名URL上传文件时,必须上传指定类型的文件。更多信息,请参见签名版本1。

示例代码

服务端示例代码

服务端生成签名URL的代码示例如下:

import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # 将替换为Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 # 将替换为Bucket名称。 bucket = oss2.Bucket(auth, '', '') # 指定过期时间,单位秒。 expire_time = 3600 # 填写Object完整路径,例如exampledir/exampleobject.png。Object完整路径中不能包含Bucket名称。 object_name = 'exampledir/exampleobject.png' def generate_presigned_url(): # 指定Header。 headers = dict() # 指定Content-Type。 headers['Content-Type'] = 'image/png' # 指定存储类型。 # headers["x-oss-storage-class"] = "Standard" # 生成签名URL时,OSS默认会对Object完整路径中的正斜线(/)进行转义,从而导致生成的签名URL无法直接使用。 # 设置slash_safe为True,OSS不会对Object完整路径中的正斜线(/)进行转义,此时生成的签名URL可以直接使用。 url = bucket.sign_url('PUT', object_name, expire_time, slash_safe=True, headers=headers) return url

客户端示例代码

Web端使用签名URL上传文件到OSS的代码示例如下:

const form = document.querySelector("form"); form.addEventListener("submit", (event) => { event.preventDefault(); const fileInput = document.querySelector("#file"); const file = fileInput.files[0]; fetch(`/get_presigned_url_for_oss_upload?filename=${file.name}`, { method: "GET" }) .then((response) => { return response.text(); }) .then((url) => { fetch(url, { method: "PUT", headers: new Headers({ 'Content-Type': 'image/png', }), body: file, }).then((res) => { console.log(res); alert('文件已上传'); }); }); }); 客户端自行拦截

对于需要限制上传文件属性的场景,您可以在客户端上通过JavaScript代码来实现。通过条件语句检查文件大小和文件类型是否满足要求,如果不满足,则弹出警告或错误信息,阻止上传操作。需要注意的是,STS临时访问凭证不支持设置限制上传文件的大小及类型。因此,如果STS临时访问凭证被截取,恶意用户可能会绕过客户端限制,直接上传恶意文件到您的OSS。

示例代码

客户端示例代码

使用元素的files属性和accept属性来检查文件大小和文件类型是否符合要求的示例代码如下:

文件上传 上传 function uploadFile() { const fileInput = document.getElementById('file-upload'); const file = fileInput.files[0]; // 文件大小限制(单位:字节) const maxFileSize = 1024 * 1024; // 1MB // 允许的文件类型 const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']; if (file) { // 检查文件大小 if (file.size > maxFileSize) { alert('文件大小超过限制。请上传小于1MB的文件。'); return; } // 检查文件类型 if (!allowedTypes.includes(file.type)) { alert('不支持的文件类型。请上传JPEG、PNG或PDF文件。'); return; } // 文件验证通过,可以进行上传操作 // 这里可以编写具体的上传逻辑 console.log('开始上传文件:', file.name); // 上传的代码 } else { alert('请选择要上传的文件。'); } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3