Object Storage Service (OSS) バケットにアップロードできるファイルの種類とサイズを制限しない場合、バケットには、ユーザーがアップロードした大きなオブジェクトや悪意のあるオブジェクトが含まれている可能性があります。 これにより、予期しないストレージ使用量と帯域幅の消費、場合によってはバケットドメインのブロックが発生する可能性があります。 OSSには、アップロードのファイルタイプとサイズを直接制限するために使用できる個別の機能はありません。 ただし、サーバーで署名を生成するとき、またはクライアント側で制限ロジックを記述するときに、ファイルの種類とサイズに制限を指定できます。
サーバー側でPOSTリクエストの署名とポリシーを生成する
アップロードするオブジェクトの属性を制限するシナリオでは、PostObject操作を呼び出すために必要な署名やポリシーなどの情報をアプリケーションサーバーから取得できます。 その後、クライアントは取得した情報を使用して、OSS SDKを使用せずにオブジェクトをアップロードできます。 サーバーによって生成されたポリシーを使用して、オブジェクトのサイズやタイプなど、アップロードするオブジェクトの属性を制限できます。 このソリューションは、HTMLフォームを使用したオブジェクトのアップロードに適しています。 このソリューションは、マルチパートアップロードと再開可能アップロードをサポートしていません。 詳細は、「PostObject」をご参照ください。
サンプルコード
アプリケーションサーバーのサンプルコード
次のサンプルコードは、アプリケーションサーバーから署名とポリシーを取得する方法の例を示しています。
osのインポート
hashlibからsha1をshaとしてインポート
jsonのインポート
インポートbase64
hmacのインポート
datetimeのインポート
インポート時間
# 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 ')
# <your-bucket> をバケットの名前に置き換えます。
bucket = '<your-bucket>'
# hostをbucketname.endpoint形式の値に設定します。 <your-bucket> をバケットの名前に置き換えます。 <your-endpoint> をOSSエンドポイントに置き換えます。 例: oss-cn-hangzhou.aliyuncs.com。
host = 'https://<your-bucket>.<your-endpoint>'
# OSSにアップロードするオブジェクトのプレフィックスを指定します。
upload_dir = 'user-dir-prefix/'
# 署名とポリシーの有効期間を指定します。 単位は秒です。
expire_time = 3600
def generate_expailation (秒):
"""
有効期限は、指定された有効期間に基づいて計算されます。 単位は秒です。
: param seconds: 有効期間 (秒) 。
: return: ISO 8601標準のtime文字列。 例: 2014-12-01T12:00:00.000Z
"""
now = int(time.time())
expiration_time = now + 秒
gmt = datetime.datetime.utcfromtimestamp(expiration_time). isofformat ()
gmt += 'Z'
gmtを返す
def generate_signature(access_key_secret、有効期限、条件、policy_extra_props=なし):
"""
署名文字列を生成します。
: param access_key_secret: バケットへのアクセス権限を持つAccessKeyシークレット。
: param expiration: 署名の有効期限が切れる時刻。 時刻を ISO 8601 規格 (yyyy-MM-ddTHH:mm:ssZ) の形式で指定します。 例: 2014-12-01T12:00:00.000Z
: param条件: フォームのアップロード中に設定できる値を制限するために使用できるポリシー条件。
: param policy_extra_props: 追加のポリシーパラメーター。 ポリシーで追加のパラメーターがサポートされている場合は、dictを使用して追加のパラメーターを渡すことができます。
: return: 署名文字列。
"""
policy_dict = {
'expiration': 有効期限、
'conditions': 条件
}
policy_extra_propsが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()
リターンsign_result.decode()
def generate_upload_params():
policy = {
# ポリシーの有効期間。
"expailation": generate_expailation (expire_time) 、
# ポリシーフィールドで条件を指定します。
"conditions": [
# success_action_redirectが指定されていない場合、アップロードが成功した後に返されるHTTPステータスコードは204されます。
["eq" 、"$success_action_status" 、"200"] 、
# フォームフィールドの値は、指定されたプレフィックスで始まる必要があります。 たとえば、キーフォームフィールドの値がuser/user1で始まる場合、条件は ["starts-with", "$key", "user/user1"] です。
["starts-with" 、"$key" 、upload_dir] 、
# アップロードするオブジェクトの最小サイズと最大サイズを指定します。 単位:バイト
["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 ': ホスト、
'dir': upload_dir
# 追加のパラメーターを指定します。
}
を返すjson.dumps (応答)
クライアントのサンプルコード
次のサンプルコードは、署名とポリシーを使用してwebクライアントから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())
. その後 (data => {
const formData=新しい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は最後のフォームフィールドでなければなりません。 他のフォームフィールドの注文は必要ありません。
formData.append('file' 、ファイル);
fetch(data.host, { method: 'POST', body: formData },).then((res) => {
console.log(res);
alert ('Object Uploaded');
});
})
. catch(error => {
console.log('OSSアップロードパラメータの取得中にエラーが発生しました:' 、エラー);
});
});
サーバー側で署名付きURLを生成
content-length-range
フィールドは、URL署名ではサポートされていません。 したがって、この方法を使用して、アップロードするファイルのサイズを制限することはできません。 アップロードを特定のファイルタイプに制限する場合は、サーバーが指定されたURLを生成するように設定するときに、Content-Type
ヘッダーを指定できます。 クライアントが署名付きURLを使用してファイルをアップロードする場合、ファイルは指定された形式のいずれかである必要があります。 詳細については、「URLへの署名の追加」をご参照ください。
サンプルコード
アプリケーションサーバーのサンプルコード
次のサンプルコードは、アプリケーションサーバーから署名付きURLを取得する方法の例を示しています。
クライアントのサンプルコード
次のサンプルコードは、署名付きURLを使用してwebクライアントからOSSにオブジェクトをアップロードする方法の例を示しています。
クライアント側の制限の実装
クライアント側でJavaScriptコードを使用して、特定のファイル属性要件を満たすファイルのアップロードを許可できます。 アップロードを特定のファイルの種類とサイズに制限するには、条件文を使用して、アップロードするファイルが指定された要件を満たしているかどうかを確認します。 そうである場合、アップロードは許可されます。 いいえの場合、アップロードは拒否され、警告またはエラーメッセージが返されます。 セキュリティトークンサービス (STS) によって提供される一時的なアクセス資格情報を使用するアップロードでは、クライアント側の制限の実装は有効ではないことに注意してください。 一時的なアクセス資格情報が漏洩した場合、悪意のあるユーザーはクライアント側の制限を回避し、悪意のあるコンテンツをOSSバケットにアップロードする可能性があります。
サンプルコード
クライアント側の制限
次のサンプルコードでは、<input type="file">
要素のfiles
属性とaccept
属性を使用して、ファイルサイズとファイルタイプが要件を満たしているかどうかを確認します。
<!DOCTYPE html>
<html>
<ヘッド>
<title> ファイルのアップロード </title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<input type="file" id="file-upload" accept="image/jpeg, image/png, application/pdf" />
<button onclick="uploadFile()"> アップロード </button>
<script>
関数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 (ファイル) {
// ファイルサイズを指定します。
if (file.size > maxFileSize) {
alert('ファイルサイズが制限を超えています。 アップロードするファイルのサイズは1 MB未満である必要があります。 ');
return;
}
// ファイルタイプを確認します。
if (!allowedTypes.include (file.type)) {
alert ('サポートされていないファイルタイプ。 許可されているファイルタイプは、JPEG、PNG、およびPDFです。 ');
return;
}
// ファイルはアップロード要件を満たしており、アップロードできます。
// アップロードロジックを記述します。
console.log('Upload file:'、file.name);
// アップロード実装コードを記述します。
} else {
alert('アップロードするファイルを選択します。 ');
}
}
</script>
</body>
</html>