tencent cloud

Cloud Object Storage

Release Notes and Announcements
Release Notes
Announcements
Product Introduction
Overview
Features
Use Cases
Strengths
Concepts
Regions and Access Endpoints
Specifications and Limits
Service Regions and Service Providers
Billing
Billing Overview
Billing Method
Billable Items
Free Tier
Billing Examples
Viewing and Downloading Bill
Payment Overdue
FAQs
Getting Started
Console
Getting Started with COSBrowser
User Guide
Creating Request
Bucket
Object
Data Management
Batch Operation
Global Acceleration
Monitoring and Alarms
Operations Center
Data Processing
Content Moderation
Smart Toolbox
Data Processing Workflow
Application Integration
User Tools
Tool Overview
Installation and Configuration of Environment
COSBrowser
COSCLI (Beta)
COSCMD
COS Migration
FTP Server
Hadoop
COSDistCp
HDFS TO COS
GooseFS-Lite
Online Tools
Diagnostic Tool
Use Cases
Overview
Access Control and Permission Management
Performance Optimization
Accessing COS with AWS S3 SDK
Data Disaster Recovery and Backup
Domain Name Management Practice
Image Processing
Audio/Video Practices
Workflow
Direct Data Upload
Content Moderation
Data Security
Data Verification
Big Data Practice
COS Cost Optimization Solutions
Using COS in the Third-party Applications
Migration Guide
Migrating Local Data to COS
Migrating Data from Third-Party Cloud Storage Service to COS
Migrating Data from URL to COS
Migrating Data Within COS
Migrating Data Between HDFS and COS
Data Lake Storage
Cloud Native Datalake Storage
Metadata Accelerator
GooseFS
Data Processing
Data Processing Overview
Image Processing
Media Processing
Content Moderation
File Processing Service
File Preview
Troubleshooting
Obtaining RequestId
Slow Upload over Public Network
403 Error for COS Access
Resource Access Error
POST Object Common Exceptions
API Documentation
Introduction
Common Request Headers
Common Response Headers
Error Codes
Request Signature
Action List
Service APIs
Bucket APIs
Object APIs
Batch Operation APIs
Data Processing APIs
Job and Workflow
Content Moderation APIs
Cloud Antivirus API
SDK Documentation
SDK Overview
Preparations
Android SDK
C SDK
C++ SDK
.NET(C#) SDK
Flutter SDK
Go SDK
iOS SDK
Java SDK
JavaScript SDK
Node.js SDK
PHP SDK
Python SDK
React Native SDK
Mini Program SDK
Error Codes
Harmony SDK
Endpoint SDK Quality Optimization
Security and Compliance
Data Disaster Recovery
Data Security
Cloud Access Management
FAQs
Popular Questions
General
Billing
Domain Name Compliance Issues
Bucket Configuration
Domain Names and CDN
Object Operations
Logging and Monitoring
Permission Management
Data Processing
Data Security
Pre-signed URL Issues
SDKs
Tools
APIs
Agreements
Service Level Agreement
Privacy Policy
Data Processing And Security Agreement
Contact Us
Glossary

Upload Objects Practice Tutorial

PDF
Mode fokus
Ukuran font
Terakhir diperbarui: 2026-01-26 14:53:10
This document describes how to set up a secure temporary key service and how to use the WeChat Mini Program SDK to initialize and upload.
Note:
Before starting the upload, ensure that you have completed the Mini Program allowlist configuration and finished the SDK initialization.

Solution strengths

Permission security: It can effectively restrict the permission scope to only allow uploading to a specified file path.
Path security: The random COS file path is determined by the server, which can effectively avoid the problem of existing files being overwritten and security risks.

Upload Process

1. The client selects a file. The client sends the original filename to the server.
2. The server generates a random COS file path with a timestamp based on the file name suffix, applies for a temporary key with corresponding permissions and the cos key, and returns them to the frontend.
3. The frontend uses the uploadFile advanced upload API to upload files to COS.

Temporary Key Establishment

Temporary key (Temporary access credentials) is a permission-restricted key obtained through the CAM TencentCloud API interface. When a COS API request is initiated, the three fields—TmpSecretId, TmpSecretKey, and Token—from the temporary key obtaining interface's returned information are used to calculate the signature.
The getKeyAndCredentials interface returns temporary key information along with the Bucket, Region, and cosKey required for upload.
The following sample code in various languages:
NodeJS
Go
PHP
Python
Java
.Net
Complete code can refer to sample code.
// Temporary key service example
const STS = require('qcloud-cos-sts');
const express = require('express');
const pathLib = require('path');
// Configure parameters
const config = {
secretId: process.env.SecretId,
secretKey: process.env.SecretKey,
proxy: process.env.Proxy,
durationSeconds: 1800,
bucket: process.env.Bucket,
region: process.env.Region,
// List of upload operation permissions for keys
allowActions: [
// Simple upload
'name/cos:PutObject',
// Multipart upload
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload',
],
};

// Generating the COS file path and name to be uploaded
const generateCosKey = function (ext) {
const date = new Date();
const m = date.getMonth() + 1;
const ymd = `${date.getFullYear()}${m < 10 ? `0${m}` : m}${date.getDate()}`;
const r = ('000000' + Math.random() * 1000000).slice(-6);
const cosKey = `file/${ymd}/${ymd}_${r}${ext ? `${ext}` : ''}`;
return cosKey;
};
// Create temporary key service
const app = express();
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
// Obtain temporary keys
function getSts({ cosKey, condition }) {
return new Promise((resolve, reject) => {
// Obtain temporary keys
const AppId = config.bucket.substr(config.bucket.lastIndexOf('-') + 1);
let resource =
'qcs::cos:' +
config.region +
':uid/' +
AppId +
':' +
config.bucket +
'/' +
cosKey;
console.log('Check if the resource is correct', resource);
const policy = {
version: '2.0',
statement: [
{
action: config.allowActions,
effect: 'allow',
resource: [
// cos related authorization path
resource,
// ci related authorization path, use as needed
// 'qcs::ci:' + config.region + ':uid/' + AppId + ':bucket/' + config.bucket + '/' + 'job/*',
],
condition
},
],
};
const startTime = Math.round(Date.now() / 1000);
STS.getCredential(
{
secretId: config.secretId,
secretKey: config.secretKey,
proxy: config.proxy,
region: config.region,
durationSeconds: config.durationSeconds,
// endpoint: 'sts.internal.tencentcloudapi.com', // supports setting the sts private network domain
policy: policy,
},
function (err, tempKeys) {
if (tempKeys) tempKeys.startTime = startTime;
if (err) {
reject(err);
} else {
resolve(tempKeys);
}
}
);
});
}
// Returns temporary keys and upload information; the client calculates the signature on its own.
app.get('/getKeyAndCredentials', function (req, res, next) {
// The business implements user login status verification independently, such as token verification.
// const userToken = req.query.userToken;
// const canUpload = checkUserRole(userToken);
// if (!canUpload) {
// res.send({ error: 'The current user does not have upload permission' });
// return;
// }

// Upload files can control the type and size, enable as needed
const permission = {
limitExt: false, // Limit file extensions for upload
extWhiteList: ['jpg', 'jpeg', 'png', 'gif', 'bmp'], // allowed file extensions
limitContentType: false, // limit upload contentType
limitContentLength: false, // limit upload file size
};
// The client passes the original file name; a random Key is generated here based on the file extension.
const filename = req.query.filename;
if (!filename) {
res.send({ error: 'Please pass the file name' });
}
const ext = pathLib.extname(filename);
const cosKey = generateCosKey(ext);
const condition = {};
// 1. Limit file extensions for upload
if (permission.limitExt) {
const extInvalid = !ext || !extWhiteList.includes(ext);
if (extInvalid) {
res.send({ error: 'Unauthorized file, upload is not allowed' });
}
}
// 2. Limit upload file content-type
if (permission.limitContentType) {
Object.assign(condition, {
'string_like_if_exist': {
// Only allow image content-types for upload
'cos:content-type': 'image/*'
}
});
}

// 3. Limit upload file size
if (permission.limitContentLength) {
Object.assign(condition, {
'numeric_less_than_equal': {
// Upload size limit cannot exceed 5MB (only applies to simple uploads)
'cos:content-length': 5 * 1024 * 1024
},
});
}

getSts({ cosKey, condition })
.then((data) => {
res.send(
Object.assign(data, {
startTime: Math.round(Date.now() / 1000),
bucket: config.bucket,
region: config.region,
key: cosKey,
})
);
})
.catch((err) => {
console.log('sts error', err);
res.send(err);
});
});

app.all('*', function (req, res, next) {
res.send({ code: -1, message: '404 Not Found' });
});
// Start the signature service
app.listen(3000);
console.log('app is listening at http://127.0.0.1:3000');
Complete code can refer to sample code.
package main

import (
"fmt"
"github.com/tencentyun/qcloud-cos-sts-sdk/go"
"math/rand"
"os"
"time"
)

type Config struct {
filename string
appId string
SecretId string
SecretKey string
Proxy string
DurationSeconds int
Bucket string
Region string
AllowActions []string
}

type Permission struct {
LimitExt bool `json:"limitExt"`
ExtWhiteList []string `json:"extWhiteList"`
LimitContentType bool `json:"limitContentType"`
LimitContentLength bool `json:"limitContentLength"`
}

func generateCosKey(ext string) string {
date := time.Now()
m := int(date.Month()) + 1
ymd := fmt.Sprintf("%d%02d%d", date.Year(), m, date.Day())
r := fmt.Sprintf("%06d", rand.Intn(1000000))
cosKey := fmt.Sprintf("file/%s/%s_%s.%s", ymd, ymd, r, ext)
return cosKey
}

func getPermission() Permission {
permission := Permission{
LimitExt: false,
ExtWhiteList: []string{"jpg", "jpeg", "png", "gif", "bmp"},
LimitContentType: false,
LimitContentLength: false,
}
return permission
}

func getConfig() Config {
config := Config{
filename: "test.jpg",
appId: "12500000000",
SecretId: os.Getenv("SECRETID"), // User's SecretId. It is recommended to use sub-account keys and follow the principle of least privilege for authorization to reduce usage risks. For obtaining sub-account keys, refer to https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1
SecretKey: os.Getenv("SECRETKEY"), // User's SecretKey. It is recommended to use sub-account keys and follow the principle of least privilege for authorization to reduce usage risks. For obtaining sub-account keys, refer to https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1
Proxy: os.Getenv("Proxy"),
DurationSeconds: 1800,
Bucket: "bucket-12500000000",
Region: "ap-guangzhou",
AllowActions: []string{
"name/cos:PutObject",
"name/cos:InitiateMultipartUpload",
"name/cos:ListMultipartUploads",
"name/cos:ListParts",
"name/cos:UploadPart",
"name/cos:CompleteMultipartUpload",
},
}
return config
}

func stringInSlice(str string, list []string) bool {
for _, v := range list {
if v == str {
return true
}
}
return false
}

func StructToCamelMap(input interface{}) map[string]interface{} {
v := reflect.ValueOf(input)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

result := make(map[string]interface{})
typ := v.Type()

for i := 0; i < v.NumField(); i++ {
field := typ.Field(i)
fieldValue := v.Field(i)

// Convert field names to camelCase
key := toLowerCamel(field.Name)

// Handle nested structs
if fieldValue.Kind() == reflect.Struct ||
(fieldValue.Kind() == reflect.Ptr && fieldValue.Elem().Kind() == reflect.Struct) {

if fieldValue.IsNil() && fieldValue.Kind() == reflect.Ptr {
result[key] = nil
continue
}

result[key] = StructToCamelMap(fieldValue.Interface())
} else {
// Handle primitive types
result[key] = fieldValue.Interface()
}
}

return result
}

// Convert to camelCase format (first letter lowercase)
func toLowerCamel(s string) string {
if s == "" {
return s
}

// Handle all-uppercase words (e.g., ID)
if strings.ToUpper(s) == s {
return strings.ToLower(s)
}

// Standard camelCase conversion
runes := []rune(s)
runes[0] = unicode.ToLower(runes[0])
return string(runes)
}

func main() {

config := getConfig()

permission := getPermission()

c := sts.NewClient(
// Obtain the key through environment variables; the os.Getenv method represents obtaining environment variables
config.SecretId, //os.Getenv("SECRETID"), // User's SecretId. It is recommended to use sub-account keys and follow the principle of least privilege for authorization to reduce usage risks. For obtaining sub-account keys, refer to https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1
config.SecretKey, //os.Getenv("SECRETKEY"), // User's SecretKey. It is recommended to use sub-account keys and follow the principle of least privilege for authorization to reduce usage risks. For obtaining sub-account keys, refer to https://www.tencentcloud.com/document/product/598/37140?from_cn_redirect=1
nil,
// sts.Host("sts.internal.tencentcloudapi.com"), // Set the domain, default domain sts.tencentcloudapi.com
// sts.Scheme("http"), // Set the protocol, default is https. Public cloud sts does not allow obtaining temporary keys via http; set http only in specific scenarios.
)

condition := make(map[string]map[string]interface{})

segments := strings.Split(config.filename, ".")
if len(segments) == 0 {
//ext := ""
}
ext := segments[len(segments)-1]

if permission.LimitExt {
extInvalid := ext == "" || !stringInSlice(ext, permission.ExtWhiteList)
if extInvalid {
fmt.Printf("%+v\\n", "Unauthorized file, upload is not allowed")
return
}
}

if permission.LimitContentType {
condition["string_like_if_exist"] = map[string]interface{}{
// Only allow image content-types for upload
"cos:content-type": "image/*",
}
}

// 3. Limit upload file size
if permission.LimitContentLength {
condition["numeric_less_than_equal"] = map[string]interface{}{
// The upload size limit cannot exceed 5MB (only applies to simple uploads)
"cos:content-length": 5 * 1024 * 1024,
}
}

key := generateCosKey(ext)
// Policy Overview https://www.tencentcloud.com/document/product/436/18023?from_cn_redirect=1
opt := &sts.CredentialOptions{
DurationSeconds: int64(config.DurationSeconds),
Region: config.Region,
Policy: &sts.CredentialPolicy{
Version: "2.0",
Statement: []sts.CredentialPolicyStatement{
{
// List of key permissions. Simple upload and multipart upload require the following permissions. For other permissions, refer to https://www.tencentcloud.com/document/product/436/31923?from_cn_redirect=1
Action: config.AllowActions,
Effect: "allow",
Resource: []string{
// Set the allowed path prefix here. You can determine the specific upload path based on the user's login status of your website. Examples: a.jpg, a/*, or * (Using wildcard * poses significant security risks; evaluate its usage carefully).
// The bucket naming format is BucketName-APPID. The bucket entered here must be in this format.
"qcs::cos:ap-guangzhou:uid/" + config.appId + ":" + config.Bucket + "/" + key,
},
// Start building the condition
// For detailed configuration rules of condition and condition types supported by COS, refer to https://www.tencentcloud.com/document/product/436/71306?from_cn_redirect=1
Condition: condition,
},
},
},
}

// case 1 Request temporary keys
res, err := c.GetCredential(opt)
if err != nil {
panic(err)
}
// Convert to camelCase map
resultMap := StructToCamelMap(res)
resultMap["bucket"] = config.Bucket
resultMap["region"] = config.Region
resultMap["key"] = key
// Print result
jsonBytes, err := json.MarshalIndent(resultMap, "", " ")
if err != nil {
panic(err)
}
// Convert to string and print
fmt.Println(string(jsonBytes))
}
Complete code can refer to sample code.
<?php
require_once __DIR__ . '/vendor/autoload.php';

use QCloud\\COSSTS\\Sts;

// Generating the COS file path and name to be uploaded
function generateCosKey($ext) {
$ymd = date('Ymd');
$r = substr('000000' . rand(), -6);
$cosKey = 'file/' . $ymd. '/' . $ymd . '_' . $r;
if ($ext) {
$cosKey = $cosKey . '.' . $ext;
}
return $cosKey;
};

// Obtain temporary keys for single-file upload permission
function getKeyAndCredentials($filename) {
// The business implements user login status verification independently, such as token verification.
// $canUpload = checkUserRole($userToken);
// if (!$canUpload) {
// return 'The current user does not have upload permission';
// }

// Upload files can control the type and size, enable as needed
$permission = array(
'limitExt' => false, // Limit file extensions for upload
'extWhiteList' => ['jpg', 'jpeg', 'png', 'gif', 'bmp'], // allowed file extensions
'limitContentType' => false, // Limit upload contentType
'limitContentLength' => false, // limit upload file size
);
$condition = array();

// The client passes the original file name; a random Key is generated here based on the file extension.
$ext = pathinfo($filename, PATHINFO_EXTENSION);

// 1. Limit file extensions for upload
if ($permission['limitExt']) {
if ($ext === '' || array_key_exists($ext, $permission['extWhiteList'])) {
return 'Unauthorized file, upload is not allowed';
}
}

// 2. Limit upload file content-type
if ($permission['limitContentType']) {
// Only allow image content-types for upload
$condition['string_like_if_exist'] = array('cos:content-type' => 'image/*');
}

// 3. Limit upload file size
if ($permission['limitContentLength']) {
// The upload size limit must not exceed 5MB (applies only to simple upload)
$condition['numeric_less_than_equal'] = array('cos:content-length' => 5 * 1024 * 1024);
}

$cosKey = generateCosKey($ext);
$bucket = 'test-131234567'; // Replace with your bucket
$region = 'ap-guangzhou'; // Replace with the region of your bucket
$config = array(
'url' => 'https://sts.tencentcloudapi.com/', // The url should match the domain
'domain' => 'sts.tencentcloudapi.com', // Domain (optional, defaults to sts.tencentcloudapi.com)
'proxy' => '',
'secretId' => getenv('GROUP_SECRET_ID'), // Permanent credentials. For plaintext credentials, enter directly as 'xxx'; must not be placed within getenv() function
'secretKey' => getenv('GROUP_SECRET_KEY'), // Permanent credentials. For plaintext credentials, enter directly as 'xxx'; must not be placed within getenv() function
'bucket' => $bucket, // Replace with your bucket
'region' => $region, // Replace with the region of your bucket
'durationSeconds' => 1800, // Validity period of the credentials
'allowPrefix' => array($cosKey), // Only grant path permission for the current key
// List of permissions granted to the temporary credentials. Simple uploads and multipart uploads require the following permissions. For other permission lists, refer to https://www.tencentcloud.com/document/product/436/31923?from_cn_redirect=1
'allowActions' => array (
// Simple upload.
'name/cos:PutObject',
// Upload in shards.
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
),
);

if (!empty($condition)) {
$config['condition'] = $condition;
}

$sts = new Sts();
$tempKeys = $sts->getTempKeys($config);
$resTemp = array_merge(
$tempKeys,
[
'startTime' => time(),
'bucket' => $bucket,
'region' => $region,
'key' => $cosKey,
]
);
echo json_encode($resTemp, JSON_UNESCAPED_SLASHES);
return $resTemp;
}
Complete code can refer to sample code.
#!/usr/bin/env python
# coding=utf-8
import json
import os
import datetime
import random

from sts.sts import Sts

if __name__ == '__main__':

# Configuration parameters
config = {
"filename":"test.jpg",
"appId": "125000000",
"secretId": os.getenv("SecretId"),
"secretKey": os.getenv("SecretKey"),
"proxy": os.getenv("Proxy"),
"durationSeconds": 1800,
"bucket": "bucket-125000000",
"region": "ap-guangzhou",
# List of upload operation permissions for keys
"allowActions": [
# Simple upload
"name/cos:PutObject",
# Multipart upload
"name/cos:InitiateMultipartUpload",
"name/cos:ListMultipartUploads",
"name/cos:ListParts",
"name/cos:UploadPart",
"name/cos:CompleteMultipartUpload",
],
}

permission = {
"limitExt": False, # Limit file extensions for upload
"extWhiteList": ["jpg", "jpeg", "png", "gif", "bmp"], # allowed file extensions
"limitContentType": False, # Limit upload contentType
"limitContentLength": False, # Limit upload file size
}


# Generating the COS file path and name to be uploaded
def generate_cos_key(ext=None):
date = datetime.datetime.now()
ymd = date.strftime('%Y%m%d')
r = str(int(random.random() * 1000000)).zfill(6)
cos_key = f"file/{ymd}/{ymd}_{r}.{ext if ext else ''}"
return cos_key


segments = config['filename'].split(".")
ext = segments[-1] if segments else ""
key = generate_cos_key(ext)
resource = f"qcs::cos:{config['region']}:uid/{config['appId']}:{config['bucket']}/{key}"

condition = {}

# 1. Limit file extensions for upload
if permission["limitExt"]:
ext_invalid = not ext or ext not in permission["extWhiteList"]
if ext_invalid:
print('Unauthorized file, upload is not allowed')

# 2. Limit upload file content-type
if permission["limitContentType"]:
condition.update({
"string_like_if_exist": {
# Only allow image content-types for upload
"cos:content-type": "image/*"
}
})

# 3. Limit upload file size
if permission["limitContentLength"]:
condition.update({
"numeric_less_than_equal": {
# Upload size limit cannot exceed 5MB (only applies to simple uploads)
"cos:content-length": 5 * 1024 * 1024
}
})


def get_credential_demo():
credentialOption = {
# Temporary key validity period in seconds
'duration_seconds': config.get('durationSeconds'),
'secret_id': config.get("secretId"),
# Fixed key
'secret_key': config.get("secretKey"),
# Replace with your bucket
'bucket': config.get("bucket"),
'proxy': config.get("proxy"),
# Replace with the bucket region
'region': config.get("region"),
"policy": {
"version": '2.0',
"statement": [
{
"action": config.get("allowActions"),
"effect": "allow",
"resource": [
resource
],
"condition": condition
}
],
},
}

try:

sts = Sts(credentialOption)
response = sts.get_credential()
credential_dic = dict(response)
credential_info = credential_dic.get("credentials")
credential = {
"bucket": config.get("bucket"),
"region": config.get("region"),
"key": key,
"startTime": credential_dic.get("startTime"),
"expiredTime": credential_dic.get("expiredTime"),
"requestId": credential_dic.get("requestId"),
"expiration": credential_dic.get("expiration"),
"credentials": {
"tmpSecretId": credential_info.get("tmpSecretId"),
"tmpSecretKey": credential_info.get("tmpSecretKey"),
"sessionToken": credential_info.get("sessionToken"),
},
}
print('get data : ' + json.dumps(credential, indent=4))
except Exception as e:
print(e)

get_credential_demo()
Complete code can refer to sample code.
package com.tencent.cloud;

import com.tencent.cloud.assumerole.AssumeRoleParam;
import com.tencent.cloud.cos.util.Jackson;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.*;

public class GetKeyAndCredentialsTest {

public static String generateCosKey(String ext) {
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String ymd = dateFormat.format(date);

Random random = new Random();
int r = random.nextInt(1000000);
String rStr = String.format("%06d", r);

String cosKey = String.format("file/%s/%s_%s.%s", ymd, ymd, rStr, ext != null ? ext : "");
return cosKey;
}

// Obtain configuration information
public TreeMap<String,Object> getConfig(){

String bucket = "test-12500000000";
String appId = "12500000000";
String filename = "test.jpg";
String region = "ap-guangzhou";
String secretId = "";
String secretKey = "";
String proxy = "";
int durationSeconds = 1800;

String[] segments = filename.split("\\\\.");
String ext = segments.length > 0 ? segments[segments.length - 1] : "";

// Temporary key restrictions
Boolean limitExt = false; // Limit file extensions for upload
List extWhiteList = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp"); // allowed file extensions
Boolean limitContentType = false; // Limit upload contentType
Boolean limitContentLength = false; // limit upload file size


Map<String, Object> condition = new HashMap();

// 1. Limit file extensions for upload
if (limitExt) {
boolean extInvalid = ext == null || !extWhiteList.contains(ext);
if (extInvalid) {
System.out.println("Unauthorized file, upload is not allowed");
return null;
}
}

// 2. Limit upload file content-type
if (limitContentType) {
condition.put("string_like_if_exist", new HashMap<String, String>() {{
put("cos:content-type", "image/*");
}});
}

// 3. Limit upload file size (applies only to simple uploads)
if (limitContentLength) {
condition.put("numeric_less_than_equal", new HashMap<String, Long>() {{
put("cos:content-length", 5L * 1024 * 1024);
}});
}
String key = generateCosKey(ext);
String resource = "qcs::cos:" + region + ":uid/" + appId + ':' + bucket + '/' + key;
List allowActions = Arrays.asList(
// Simple upload
"name/cos:PutObject",
// Multipart upload
"name/cos:InitiateMultipartUpload",
"name/cos:ListMultipartUploads",
"name/cos:ListParts",
"name/cos:UploadPart",
"name/cos:CompleteMultipartUpload"
);

// Build policy
Map<String, Object> policy = new HashMap();
policy.put("version", "2.0");
Map<String, Object> statement = new HashMap();
statement.put("action", allowActions);
statement.put("effect", "allow");
List<String> resources = Arrays.asList(
resource
);
statement.put("resource", resources);
statement.put("condition", condition);
policy.put("statement", Arrays.asList(statement));


// Build config
TreeMap <String,Object> config = new TreeMap<String, Object>();
config.put("secretId",secretId);
config.put("secretKey",secretKey);
config.put("proxy",proxy);
config.put("duration",durationSeconds);
config.put("bucket",bucket);
config.put("region",region);
config.put("key",key);
config.put("policy",Jackson.toJsonPrettyString(policy));
return config;
}

/**
* Basic example for requesting temporary credentials, suitable for granting a set of permissions to a group of object paths within a bucket
*/
@Test
public void testGetKeyAndCredentials() {
TreeMap config = this.getConfig();
try {
Response response = CosStsClient.getCredential(config);
TreeMap <String,Object> credential = new TreeMap<String, Object>();
TreeMap <String,Object> credentials = new TreeMap<String, Object>();
credentials.put("tmpSecretId",response.credentials.tmpSecretId);
credentials.put("tmpSecretKey",response.credentials.tmpSecretKey);
credentials.put("sessionToken",response.credentials.sessionToken);
credential.put("startTime",response.startTime);
credential.put("expiredTime",response.expiredTime);
credential.put("requestId",response.requestId);
credential.put("expiration",response.expiration);
credential.put("credentials",credentials);
credential.put("bucket",config.get("bucket"));
credential.put("region",config.get("region"));
credential.put("key",config.get("key"));
System.out.println(Jackson.toJsonPrettyString(credential));
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("no valid secret !");
}
}
}
Complete code can refer to sample code.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Mail;
using COSSTS;
using Newtonsoft.Json;
using Formatting = System.Xml.Formatting;


namespace COSSnippet
{
public class GetKeyAndCredentials
{
// Permanent key
string secretId = "";
string secretKey = "";

string bucket = "bucket-125000000";
string appId = "125000000";
string region = "ap-guangzhou";
string filename = "test.jpg";
int time = 1800;
// Limit
Boolean limitExt = false; // Limit file extensions for upload
List<string> extWhiteList = new List<String> { "jpg", "jpeg", "png", "gif", "bmp" }; // allowed file extensions
Boolean limitContentType = false; // Limit upload contentType
Boolean limitContentLength = false; // limit upload file size

public string generateCosKey(string ext)
{
DateTime date = DateTime.Now;
int m = date.Month;
string ymd = $"{date.Year}{(m < 10 ? $"0{m}" : m.ToString())}{date.Day}";
Random random = new Random();
string r = random.Next(0, 1000000).ToString("D6"); // Generate a 6-digit random number with leading zeros
string cosKey = $"file/{ymd}/{ymd}_{r}.{(string.IsNullOrEmpty(ext) ? "" : ext)}";
return cosKey;
}
public Dictionary<string, object> getConfig()
{
Dictionary<string, object> config = new Dictionary<string, object>();
string[] allowActions = new string[] { // Allowed operations, using upload as an example
"name/cos:PutObject",
"name/cos:PostObject",
"name/cos:InitiateMultipartUpload",
"name/cos:ListMultipartUploads",
"name/cos:ListParts",
"name/cos:UploadPart",
"name/cos:CompleteMultipartUpload",
};
string[] segments = filename.Split(".");
string ext = segments.Length > 0 ? segments[segments.Length - 1] : string.Empty;
string key = generateCosKey(ext);
string resource = $"qcs::cos:{region}:uid/{appId}:{bucket}/{key}";

var condition = new Dictionary<string, object>();
// 1. Limit file extensions for upload
if (limitExt)
{
var extInvalid = string.IsNullOrEmpty(ext) || !extWhiteList.Contains(ext);
if (extInvalid)
{
Console.WriteLine("Unauthorized file, upload is not allowed");
return null;
}
}

// 2. Limit file upload content-type
if (limitContentType)
{
condition["string_like_if_exist"] = new Dictionary<string, string>
{
{ "cos:content-type", "image/*" } // only allow image content-types for upload
};
}

// 3. Limit upload file size (applies only to simple uploads)
if (limitContentLength)
{
condition["numeric_less_than_equal"] = new Dictionary<string, long>
{
{ "cos:content-length", 5 * 1024 * 1024 } // Upload size limit cannot exceed 5MB
};
}

var policy = new Dictionary<string, object>
{
{ "version", "2.0" },
{ "statement", new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
{ "action", allowActions },
{ "effect", "allow" },
{ "resource", new List<string>
{
resource,
}
},
{ "condition", condition }
}
}
}
};

// Serialize to JSON and output
string jsonPolicy = JsonConvert.SerializeObject(policy);
config.Add("bucket", bucket);
config.Add("region", region);
config.Add("durationSeconds", time);

config.Add("secretId", secretId);
config.Add("secretKey", secretKey);
config.Add("key", key);
config.Add("policy", jsonPolicy);
return config;
}
// Obtain temporary access credentials for federated identities https://www.tencentcloud.com/document/product/1312/48195?from_cn_redirect=1
public Dictionary<string, object> GetCredential()
{

var config = getConfig();
// Obtain temporary keys
Dictionary<string, object> credential = STSClient.genCredential(config);
Dictionary<string, object> credentials = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject((object) credential["Credentials"]));
Dictionary<string, object> credentials1 = new Dictionary<string, object>();
credentials1.Add("tmpSecretId",credentials["TmpSecretId"]);
credentials1.Add("tmpSecretKey",credentials["TmpSecretKey"]);
credentials1.Add("sessionToken",credentials["Token"]);
Dictionary<string, object> dictionary1 = new Dictionary<string, object>();
dictionary1.Add("credentials",credentials1);
dictionary1.Add("startTime",credential["StartTime"]);
dictionary1.Add("requestId",credential["RequestId"]);
dictionary1.Add("expiration",credential["Expiration"]);
dictionary1.Add("expiredTime",credential["ExpiredTime"]);
dictionary1.Add("bucket",config["bucket"]);
dictionary1.Add("region",config["region"]);
dictionary1.Add("key",config["key"]);
return dictionary1;
}
static void Main(string[] args)
{
GetKeyAndCredentials m = new GetKeyAndCredentials();
Dictionary<string, object> result = m.GetCredential();
string Credentials = JsonConvert.SerializeObject(result);
Console.WriteLine($"{Credentials}");
}
}
}

Client Initiates Upload

const COS = require('./lib/cos-wx-sdk-v5.js'); // For development use
// const COS = require('./lib/cos-wx-sdk-v5.min.js'); // Use the minified version for production

// console.log(COS.version); The sdk version must be at least 1.7.2

wx.chooseMedia({
count: 9,
mediaType: ['image','video'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
uploadFile(res.tempFiles[0]);
}
});

function uploadFile(file) {
const getUploadParams = function() {
return new Promise((resolve, reject) => {
const stsUrl = `http://127.0.0.1:3000/getKeyAndCredentials?filename=${file.tempFilePath}`;
wx.request({
url: stsUrl,
dataType: 'json',
success: function (result) {
resolve(result.data);
},
fail: function() {
reject('get sts error');
}
});
});
}
const upload = async function () {
try {
const data = await getUploadParams();
// The server-side interface needs to return: the upload bucket, region, object key with a random path, and temporary credentials
console.log('getKeyAndCredentials:', data);

// Example 1: Obtaining temporary keys - If obtaining the field format of temporary keys via qcloud-cos-sts-sdk, extract temporary key information and uploaded file path information from the return value.
const { credentials = {}, startTime, expiredTime, bucket, region, key } = data;
const { tmpSecretId, tmpSecretKey, sessionToken } = credentials;

// Example 2: Obtaining temporary keys - If directly requesting the TencentCloud API or using the TencentCloud API SDK to call the temporary key interface, the response is in UpperCamelCase format
// const tmpSecretId = data.Credentials.TmpSecretId;
// const tmpSecretKey= data.Credentials.TmpSecretKey;
// const sessionToken = data.Credentials.Token;
// const expiredTime= data.ExpiredTime;
// Validate the parameters returned by getUploadParams; the actual returned format prevails
const params = { tmpSecretId, tmpSecretKey, sessionToken, bucket, region, key };
const emptyParam = Object.keys(params).find(key => !params[key]);
if (emptyParam) {
console.error(`Parameter error: ${emptyParam} cannot be empty`);
return;
}
// Create an SDK instance and pass the temporary key parameters
const cos = new COS({
SecretId: tmpSecretId,
SecretKey: tmpSecretKey,
SecurityToken: sessionToken,
StartTime: startTime,
ExpiredTime: expiredTime,
SimpleUploadMethod: 'putObject',
});
cos.uploadFile(
{
Bucket: bucket,
Region: region,
Key: key,
FilePath: file.tempFilePath,
FileSize: file.size,
SliceSize: 1024 * 1024 * 5, // Files larger than 5mb will automatically use multipart upload
},
function (err, data) {
if (err) {
console.error('Upload failed', err);
} else {
console.log('Upload succeeded', data);
}
}
);
} catch (e) {
console.error(e);
}
};
upload();
}

References



Bantuan dan Dukungan

Apakah halaman ini membantu?

masukan