tencent cloud

Cloud Object Storage

最新情報とお知らせ
製品アップデート情報
製品のお知らせ
製品概要
製品概要
機能概要
応用シナリオ
製品の優位性
基本概念
リージョンとアクセスドメイン名
仕様と制限
製品の課金
課金概要
課金方式
課金項目
無料利用枠
記帳例
請求書の確認とダウンロード
お支払い遅れについて
よくある質問
クイックスタート
コンソールクイックスタート
COSBrowserクイックスタート
ユーザーガイド
リクエストの作成
バケット
オブジェクト
データ管理
バッチ処理
グローバルアクセラレーション
監視とアラーム
運用管理センター
データ処理
インテリジェントツールボックス使用ガイド
データワークフロー
アプリ統合
ツールガイド
ツール概要
環境のインストールと設定
COSBrowserツール
COSCLIツール
COSCMDツール
COS Migrationツール
FTP Serverツール
Hadoopツール
COSDistCpツール
HDFS TO COSツール
オンラインツール (Onrain Tsūru)
セルフ診断ツール
実践チュートリアル
概要
アクセス制御と権限管理
パフォーマンスの最適化
AWS S3 SDKを使用したCOSアクセス
データディザスタリカバリバックアップ
ドメイン名管理の実践
画像処理の実践
COSオーディオビデオプレーヤーの実践
データセキュリティ
データ検証
COSコスト最適化ソリューション
サードパーティアプリケーションでのCOSの使用
移行ガイド
サードパーティクラウドストレージのデータをCOSへ移行
データレークストレージ
クラウドネイティブデータレイク
メタデータアクセラレーション
データアクセラレーター GooseFS
データ処理
データ処理概要
画像処理
メディア処理
コンテンツ審査
ファイル処理
ドキュメントプレビュー
トラブルシューティング
RequestId取得の操作ガイド
パブリックネットワーク経由でのCOSへのファイルアップロード速度の遅さ
COSへのアクセス時に403エラーコードが返される
リソースアクセス異常
POST Objectの一般的な異常
セキュリティとコンプライアンス
データ災害復帰
データセキュリティ
クラウドアクセスマネジメント
よくある質問
よくあるご質問
一般的な問題
従量課金に関するご質問
ドメインコンプライアンスに関するご質問
バケット設定に関する質問
ドメイン名とCDNに関するご質問
ファイル操作に関するご質問
権限管理に関するご質問
データ処理に関するご質問
データセキュリティに関するご質問
署名付きURLに関するご質問
SDKクラスに関するご質問
ツール類に関するご質問
APIクラスに関するご質問
Agreements
Service Level Agreement
プライバシーポリシー
データ処理とセキュリティ契約
連絡先
用語集
ドキュメントCloud Object Storage

Upload Object Hands-on Tutorial

フォーカスモード
フォントサイズ
最終更新日: 2026-02-27 15:15:44
This document describes how to set up a secure temporary key service and how to initialize and upload using the iOS SDK.

Solution strengths

Permission security: It can effectively restrict the secure permission scope and only allow uploads 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 the file and sends the original filename to the server.
2. Based on the file name suffix, the server generates a timestamped random COS file path, applies for a temporary key and cos key with corresponding permissions, and returns them to the frontend.
3. The iOS client uses the advanced upload API to upload files to COS.

Temporary Key Setup

Temporary Keys (Temporary Access Credentials) are credentials with limited permissions obtained through the CAM TencentCloud API. When COS API requests are initiated, three fields returned by the temporary key API are required: TmpSecretId, TmpSecretKey, and Token, which are used to calculate the signature.
The getKeyAndCredentials API returns temporary keys information along with the Bucket, Region, and cosKey required for upload.
Sample code in various languages:
NodeJS
Go
PHP
Python
Java
.Net
The complete code can be found in the sample code.
// Temporary key service example
const STS = require('qcloud-cos-sts');
const express = require('express');
const pathLib = require('path');
// Configuration 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,
// Permissions list for key upload operations
allowActions: [
// Simple upload
'name/cos:PutObject',
// Multipart upload
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload',
],
};

// Generate the file path and name for the COS upload
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 a 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();
});
// Get 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 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 private network domain for sts
policy: policy,
},
function (err, tempKeys) {
if (tempKeys) tempKeys.startTime = startTime;
if (err) {
reject(err);
} else {
resolve(tempKeys);
}
}
);
});
}
// Return temporary keys and upload information; the client independently calculates the signature
app.get('/getKeyAndCredentials', function (req, res, next) {
// The business should implement user login status validation, such as token validation
// const userToken = req.query.userToken;
// const canUpload = checkUserRole(userToken);
// if (!canUpload) {
// res.send({ error: 'The current user does not have upload permissions' });
// return;
// }

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

// 3. Limit uploaded file size
if (permission.limitContentLength) {
Object.assign(condition, {
'numeric_less_than_equal': {
// The upload size limit cannot exceed 5MB (only effective for 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');
The complete code can be found in the 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 a sub-account key; authorization follows the principle of least privilege 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 a sub-account key; authorization follows the principle of least privilege 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 basic types
result[key] = fieldValue.Interface()
}
}

return result
}

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

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

// Ordinary 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 is used to obtain environment variables.
config.SecretId, //os.Getenv("SECRETID"), // User's SecretId. It is recommended to use a sub-account key; authorization follows the principle of least privilege 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 a sub-account key; authorization follows the principle of least privilege 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. The default domain is sts.tencentcloudapi.com
// sts.Scheme("http"), // Set the protocol (defaults to https). In the public cloud, sts does not allow http for obtaining temporary keys; set http only in special 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", "Illegal file, upload prohibited")
return
}
}

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

// 3. Limit uploaded file size
if permission.LimitContentLength {
condition["numeric_less_than_equal"] = map[string]interface{}{
// The upload size limit cannot exceed 5MB (only effective for 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{
{
// Permissions list for keys. Simple upload and multipart upload require the following permissions. For other permissions, see https://www.tencentcloud.com/document/product/436/31923?from_cn_redirect=1
Action: config.AllowActions,
Effect: "allow",
Resource: []string{
// Modify this to the allowed path prefix. You can determine the specific upload path based on the user login status of your website, for example: a.jpg, a/*, or * (using wildcard * poses significant security risks; evaluate its use carefully)
// The bucket naming format is BucketName-APPID. The bucket filled in here must follow this format.
"qcs::cos:ap-guangzhou:uid/" + config.appId + ":" + config.Bucket + "/" + key,
},
// Start building the condition
// For detailed setting rules of condition and the condition types supported by COS, see 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 the result
jsonBytes, err := json.MarshalIndent(resultMap, "", " ")
if err != nil {
panic(err)
}
// Convert to string and print
fmt.Println(string(jsonBytes))
}
The complete code can be found in the sample code.
<?php
require_once __DIR__ . '/vendor/autoload.php';

use QCloud\\COSSTS\\Sts;

// Generate the file path and name for the COS upload
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 authorization
function getKeyAndCredentials($filename) {
// The business should implement user login status validation, such as token validation
// $canUpload = checkUserRole($userToken);
// if (!$canUpload) {
// return 'The current user does not have upload permissions';
// }

// Upload files; control the types and sizes that can be uploaded, and enable as needed
$permission = array(
'limitExt' => false, // Limit uploaded file extensions
'extWhiteList' => ['jpg', 'jpeg', 'png', 'gif', 'bmp'], // Allowed file extensions
'limitContentType' => false, // Limit upload content type
'limitContentLength' => false, // Limit uploaded file size
);
$condition = array();

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

// 1. Limit uploaded file extensions
if ($permission['limitExt']) {
if ($ext === '' || array_key_exists($ext, $permission['extWhiteList'])) {
return 'Illegal file, upload prohibited';
}
}

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

// 3. Limit uploaded file size
if ($permission['limitContentLength']) {
// The upload size limit must not exceed 5MB (applies only to simple uploads)
$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 where your bucket is located
$config = array(
'url' => 'https://sts.tencentcloudapi.com/', // The url should be consistent with the domain
'domain' => 'sts.tencentcloudapi.com', // Domain name, optional, defaults to sts.tencentcloudapi.com
'proxy' => '',
'secretId' => getenv('GROUP_SECRET_ID'), // Fixed secret key. If it's a plaintext secret key, please directly enter it as 'xxx', do not put it in the getenv() function.
'secretKey' => getenv('GROUP_SECRET_KEY'), // Fixed secret key. If it's a plaintext secret key, please directly enter it as 'xxx', do not put it in the getenv() function.
'bucket' => $bucket, // Replace with your bucket
'region' => $region, // Replace with the region where your bucket is located
'durationSeconds' => 1800, // Validity period of the key
'allowPrefix' => array($cosKey), // Only grant path permissions for the current key
// The list of permissions for the key. The following permissions are required for simple uploads and multipart uploads. 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;
}
The complete code can be found in the 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",
# Permissions List for Key Upload Operations
"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 uploaded file extensions
"extWhiteList": ["jpg", "jpeg", "png", "gif", "bmp"], # Allowed file extensions
"limitContentType": False, # Restrict upload content type
"limitContentLength": False, # Limit uploaded file size
}


# Generate the file path and file name for uploading to COS
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 uploaded file extensions
if permission["limitExt"]:
ext_invalid = not ext or ext not in permission["extWhiteList"]
if ext_invalid:
print('Illegal file, upload prohibited')

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

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


def get_credential_demo():
credentialOption = {
# Validity period of temporary credentials, 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 region where your bucket is located
'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()
The complete code can be found in the 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 limitations
Boolean limitExt = false; // Limit uploaded file extensions
List extWhiteList = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp"); // Allowed file extensions
Boolean limitContentType = false; // Restrict upload content type
Boolean limitContentLength = false; // Limit uploaded file size


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

// 1. Limit uploaded file extensions
if (limitExt) {
boolean extInvalid = ext == null || !extWhiteList.contains(ext);
if (extInvalid) {
System.out.println("Illegal file, upload prohibited");
return null;
}
}

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

// 3. Limit uploaded 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, which is suitable for granting a set of operations permissions for a batch of object keys 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 !");
}
}
}
The complete code can be found in the 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 secret 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 uploaded file extensions
List<string> extWhiteList = new List<String> { "jpg", "jpeg", "png", "gif", "bmp" }; // Allowed file extensions
Boolean limitContentType = false; // Restrict upload content type
Boolean limitContentLength = false; // Limit uploaded 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 scope, using upload operation 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 uploaded file extensions
if (limitExt)
{
var extInvalid = string.IsNullOrEmpty(ext) || !extWhiteList.Contains(ext);
if (extInvalid)
{
Console.WriteLine("Illegal file, upload prohibited");
return null;
}
}

// 2. Limit uploaded file content-type
if (limitContentType)
{
condition["string_like_if_exist"] = new Dictionary<string, string>
{
{ "cos:content-type", "image/*" } // Only allow uploading files with image content-type
};
}

// 3. Limit uploaded file size (applies only to simple uploads)
if (limitContentLength)
{
condition["numeric_less_than_equal"] = new Dictionary<string, long>
{
{ "cos:content-length", 5 * 1024 * 1024 } // The 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 federated identity temporary access credentials 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

For detailed usage steps, refer to Quick Start.

// 1. Initialize COS SDK. It only needs to be initialized once. It is recommended to do this when the app starts.
QCloudServiceConfiguration *configuration = [QCloudServiceConfiguration new];
configuration.appID = @"1250000000";
QCloudCOSXMLEndPoint *endpoint = [[QCloudCOSXMLEndPoint alloc] init];
endpoint.regionName = @"ap-guangzhou";
configuration.endpoint = endpoint;
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:configuration];

// 2. Call the business service sts API to obtain temporary keys

__block NSDictionary * credentialsInfo;
[[[NSURLSession sharedSession]dataTaskWithURL:[NSURL URLWithString:@"http://******"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// Request temporary keys from the business service API.
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingTopLevelDictionaryAssumed error:nil];
credentialsInfo = dic;
NSDictionary * credentials = dic[@"credentials"];
QCloudCredential *credential = [QCloudCredential new];
credential.secretID = credentials[@"tmpSecretId"];
credential.secretKey = credentials[@"tmpSecretKey"];
credential.token = credentials[@"sessionToken"];
// Signature expiration time
credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:[dic[@"expiredTime"] integerValue]];
credential.startDate = [NSDate dateWithTimeIntervalSince1970:[dic[@"startTime"] integerValue]];;
QCloudAuthentationV5Creator *creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:credential];
continueBlock(creator, nil);
}] resume];

// 3. Use QCloudCOSXMLUploadObjectRequest to start the upload.
QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];

// Temporary credentials requested from the business API
QCloudCredential *credential = [QCloudCredential new];
// Set the requested temporary keys to the QCloudCOSXMLUploadObjectRequest instance.
put.credential = credential;
/** Local file path. Please ensure the URL starts with file://, as shown below:
1. [NSURL URLWithString:@"file:////var/mobile/Containers/Data/Application/DBPF7490-D5U8-4ABF-A0AF-CC49D6A60AEB/Documents/exampleobject"]
2. [NSURL fileURLWithPath:@"/var/mobile/Containers/Data/Application/DBPF7490-D5U8-4ABF-A0AF-CC49D6A60AEB/Documents/exampleobject"]
*/
NSURL* url = [NSURL fileURLWithPath:@"file URL"];
// The bucket name is composed of BucketName-Appid and can be viewed in the COS console at https://console.tencentcloud.com/cos5/bucket
put.bucket = credentialsInfo[@"bucket"];
// The object key is the full path of the object on COS. If it includes a directory, the format should be "video/xxx/movie.mp4"
put.object = credentialsInfo[@"key"];
put.regionName = credentialsInfo[@"region"];
// The content of the object to be uploaded. You can pass in variables of type NSData* or NSURL*
put.body = url;
// Monitor the upload progress
[put setSendProcessBlock:^(int64_t bytesSent,
int64_t totalBytesSent,
int64_t totalBytesExpectedToSend) {
// bytesSent The number of bytes to be sent this time (a large file may be sent in multiple parts)
// totalBytesSent The number of bytes sent
// totalBytesExpectedToSend The total number of bytes expected to be sent in this upload (which is the file size)
}];
// Listen for the upload result
[put setFinishBlock:^(QCloudUploadObjectResult *result, NSError *error) {
// Get the download URL of the uploaded file from the upload result result.location
NSString * fileUrl = result.location;
// Obtain the file crc64
NSString * crc64 = [[outputObject __originHTTPURLResponse__].allHeaderFields valueForKey:@"x-cos-hash-crc64ecma"];
}];
[put setInitMultipleUploadFinishBlock:^(QCloudInitiateMultipartUploadResult *
multipleUploadInitResult,
QCloudCOSXMLUploadObjectResumeData resumeData) {
// After the multipart upload initialization is completed, this block will be called back, where you can obtain resumeData and uploadid
NSString* uploadId = multipleUploadInitResult.uploadId;
}];
[[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];

The complete client code can be found in the sample code.

References

For upload error issues, please refer to iOS SDK FAQ.
For how to securely upload objects, please refer to Upload Security Restrictions.

ヘルプとサポート

この記事はお役に立ちましたか?

フィードバック