tencent cloud

对象存储

动态与公告
产品动态
产品公告
产品简介
产品概述
功能概览
应用场景
产品优势
基本概念
地域和访问域名
规格与限制
产品计费
计费概述
计费方式
计费项
免费额度
计费示例
查看和下载账单
欠费说明
常见问题
快速入门
控制台快速入门
COSBrowser 快速入门
用户指南
创建请求
存储桶
对象
数据管理
批量处理
全球加速
监控与告警
运维中心
数据处理
内容审核
智能工具箱
数据工作流
应用集成
工具指南
工具概览
环境安装与配置
COSBrowser 工具
COSCLI 工具
COSCMD 工具
COS Migration 工具
FTP Server 工具
Hadoop 工具
COSDistCp 工具
HDFS TO COS 工具
GooseFS-Lite 工具
在线辅助工具
自助诊断工具
实践教程
概览
访问控制与权限管理
性能优化
使用 AWS S3 SDK 访问 COS
数据容灾备份
域名管理实践
图片处理实践
COS 音视频播放器实践
工作流实践
数据直传
内容审核实践
数据安全
数据校验
大数据实践
COS 成本优化解决方案
在第三方应用中使用 COS
迁移指南
本地数据迁移至 COS
第三方云存储数据迁移至 COS
以 URL 作为源地址的数据迁移至 COS
COS 之间数据迁移
Hadoop 文件系统与 COS 之间的数据迁移
数据湖存储
云原生数据湖
元数据加速
数据加速器 GooseFS
数据处理
数据处理概述
图片处理
媒体处理
内容审核
文件处理
文档处理
故障处理
获取 RequestId 操作指引
通过外网上传文件至 COS 缓慢
访问 COS 时返回403错误码
资源访问异常
POST Object 常见异常
API 文档
简介
公共请求头部
公共响应头部
错误码
请求签名
操作列表
Service 接口
Bucket 接口
Object 接口
批量处理接口
数据处理接口
任务与工作流
内容审核接口
云查毒接口
SDK 文档
SDK 概览
准备工作
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
小程序 SDK
错误码
鸿蒙(Harmony) SDK
终端 SDK 质量优化
安全与合规
数据容灾
数据安全
访问管理
常见问题
热门问题
一般性问题
计费计量问题
域名合规问题
存储桶配置问题
域名和 CDN 问题
文件操作问题
日志监控问题
权限管理问题
数据处理问题
数据安全问题
预签名 URL 问题
SDK 类问题
工具类问题
API 类问题
服务协议
Service Level Agreement
隐私政策
数据处理和安全协议
联系我们
词汇表

移动应用直传实践

PDF
聚焦模式
字号
最后更新时间: 2024-01-06 10:54:03

简介

本文主要介绍基于腾讯云对象存储 COS,如何快速实现一个移动应用的文件直传功能。您的服务器上只需要生成和管理访问密钥,无需关心细节,文件数据都存放在腾讯云 COS 上。

架构说明

对于客户端应用,把永久密钥放到客户端代码中,这既容易泄露您的密钥信息,也不便于控制用户访问权限。我们建议通过在请求时携带临时密钥,您可以临时授权您的 App 访问您的存储资源,而不会泄露您的永久密钥,密钥的有效期由您指定,过期后自动失效。 COS 移动端 SDK(Android/IOS)均很好的支持了通过临时密钥来授权请求,您只需要在后台搭建一个临时密钥的服务,即可无缝给终端 COS 请求进行授权。

架构图

整体架构图如下所示:
cos接入cam框架图

其中:
用户客户端:即用户手机 App。
COS:腾讯云对象存储,负责存储 App 上传的数据。
CAM:腾讯云访问管理,用于生成 COS 的临时密钥。
用户服务端:用户自己的后台服务器,这里用于获取临时密钥,并返回给应用 App。

前提条件

1. 创建存储桶。 在 COS 控制台 上创建存储桶。按照您的需求,请将存储桶权限设置为私有读写或者公有读私有写。详细操作步骤请参见 创建存储桶设置访问权限
2. 获取永久密钥。 临时密钥需要通过永久密钥生成。请前往 API 密钥管理 获取 SecretId、SecretKey,前往 账号信息 获取 APPID。

实践步骤

搭建临时密钥服务

出于安全考虑,签名使用临时密钥,需要服务端搭建临时密钥服务,并提供 API 接口给客户端使用。具体搭建步骤请参见 临时密钥生成及使用指引
注意
正式部署时服务端请加一层您的网站本身的权限检验。

选择合适的权限

按照最小权限原则,建议您按照自己的需求,通过 Policy 控制临时密钥的权限范围。服务器下发一个完全读写权限的密钥,一旦被攻击,可能导致其他用户的数据泄露。具体的配置方法请参见 临时密钥生成及使用指引

SDK 接入授权服务

Android

搭建好临时密钥服务后,您需要将 SDK 接入到授权服务上,SDK 会负责控制请求的并发数,也会将有效的密钥缓存在本地,并在密钥失效之后重新再次请求,您无需管理获取的密钥。

标准响应体授权

如果您直接将 STS SDK 中得到的 JSON 数据作为临时密钥服务的响应体(cossign 即采用了这种方式),那么您可以使用如下代码来创建 COS SDK 中的授权类:
import android.content.Context;
import com.tencent.cos.xml.*;
import com.tencent.qcloud.core.auth.*;
import com.tencent.qcloud.core.common.*;
import com.tencent.qcloud.core.http.*;
import java.net.*;


Context context = ...;
CosXmlServiceConfig cosXmlServiceConfig = ...;

/**
* 获取授权服务的 url 地址
*/
URL url = null; // 后台授权服务的 url 地址
try {
url = new URL("your_auth_server_url");
} catch (MalformedURLException e) {
e.printStackTrace();
}

/**
* 初始化 {@link QCloudCredentialProvider} 对象,来给 SDK 提供临时密钥。
*/
QCloudCredentialProvider credentialProvider = new SessionCredentialProvider(new HttpRequest.Builder<String>()
.url(url)
.method("GET")
.build());

CosXmlService cosXmlService = new CosXmlService(context, cosXmlServiceConfig, credentialProvider);
说明
这种方式下签名的开始时间为手机本地时间,因此如果手机本地时间偏差较大(十分钟以上),可能会导致签名出错,这种情况建议使用下述的自定义响应体授权。

自定义响应体授权

如果您想获得更大的灵活性,例如自定义临时密钥服务的 HTTP 响应体,给终端返回服务器时间作为签名的开始时间,用来避免由于用户手机本地时间偏差过大导致的签名不正确,或者使用其他的协议来进行终端和服务端之间的通信,那么您可以继承 BasicLifecycleCredentialProvider 类,并实现其 fetchNewCredentials():
请先定义一个 MyCredentialProvider 类:
import android.content.Context;
import com.tencent.cos.xml.*;
import com.tencent.qcloud.core.auth.*;
import com.tencent.qcloud.core.common.*;
import com.tencent.qcloud.core.http.*;
import java.net.*;


public class MyCredentialProvider extends BasicLifecycleCredentialProvider {

@Override
protected QCloudLifecycleCredentials fetchNewCredentials() throws QCloudClientException {

// 首先从您的临时密钥服务器获取包含了签名信息的响应
....

// 然后解析响应,获取密钥信息
String tmpSecretId = ...;
String tmpSecretKey = ...;
String sessionToken = ...;
long expiredTime = ...;

// 返回服务器时间作为签名的起始时间
long beginTime = ...;

// todo something you want

// 最后返回临时密钥信息对象
return new SessionQCloudCredentials(tmpSecretId, tmpSecretKey, sessionToken, beginTime, expiredTime);
}
}
利用您定义的 MyCredentialProvider 实例来授权请求:
import android.content.Context;
import com.tencent.cos.xml.*;
import com.tencent.qcloud.core.auth.*;
import com.tencent.qcloud.core.common.*;
import com.tencent.qcloud.core.http.*;
import java.net.*;

Context context = ...;
CosXmlServiceConfig cosXmlServiceConfig = ...;

/**
* 初始化 {@link QCloudCredentialProvider} 对象,来给 SDK 提供临时密钥。
*/
QCloudCredentialProvider credentialProvider = new MyCredentialProvider();

CosXmlService cosXmlService = new CosXmlService(context, cosXmlServiceConfig, credentialProvider);
完整的示例代码请参见 Android COS Transfer Practice
更多关于 Android 如何向 COS 上传和下载文件,请参见 Android SDK 快速入门

iOS

我们提供了 QCloudCredentailFenceQueue 来方便地获取和管理临时签名。QCloudCredentailFenceQueue 提供了栅栏机制,也就是说您使用 QCloudCredentailFenceQueue 获取签名的话,所有需要获取签名的请求会等待签名完成后再执行,免去了自己管理异步过程。
使用 QCloudCredentailFenceQueue,我们需要先生成一个实例。
//AppDelegate.m
//AppDelegate需遵循QCloudCredentailFenceQueueDelegate协议
//
- (BOOL)application:(UIApplication * )application didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
// init step
self.credentialFenceQueue = [QCloudCredentailFenceQueue new];
self.credentialFenceQueue.delegate = self;
return YES;
}

然后调用 QCloudCredentailFenceQueue 的类需要遵循 QCloudCredentailFenceQueueDelegate 并实现协议内定义的方法:
- (void) fenceQueue:(QCloudCredentailFenceQueue * )queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock
当通过 QCloudCredentailFenceQueue 去获取签名时,所有需要签名的 SDK 里的请求都会等待该协议定义的方法内拿到了签名所需的参数并生成有效的签名后执行。请看以下示例:
- (void)fenceQueue:(QCloudCredentailFenceQueue *)queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock {
QCloudHTTPRequest* request = [QCloudHTTPRequest new];
request.requestData.serverURL = @“your sign service url”;//请求的URL

[request setConfigureBlock:^(QCloudRequestSerializer *requestSerializer, QCloudResponseSerializer *responseSerializer) {
requestSerializer.serializerBlocks = @[QCloudURLFuseWithURLEncodeParamters];
responseSerializer.serializerBlocks = @[QCloudAcceptRespnseCodeBlock([NSSet setWithObjects:@(200), nil],nil),//规定返回码是200以外的时候返回错误
QCloudResponseJSONSerilizerBlock];//按照JSON格式解析返回的数据
}];

[request setFinishBlock:^(id response, NSError *error) {
if (error) {
error = [NSError errorWithDomain:@"com.tac.test" code:-1111 userInfo:@{NSLocalizedDescriptionKey:@"没有获取到临时密钥"}];
continueBlock(nil, error);
} else {
QCloudCredential* crendential = [[QCloudCredential alloc] init];
crendential.secretID = response[@"data"][@"credentials"][@"tmpSecretId"];
crendential.secretKey = response[@"data"][@"credentials"][@"tmpSecretKey"];
credential.startDate =[NSDate dateWithTimeIntervalSince1970:@"返回的服务器时间"]
crendential.experationDate = [NSDate dateWithTimeIntervalSinceNow:[response[@"data"][@"expiredTime"] intValue]];
crendential.token = response[@"data"][@"credentials"][@"sessionToken"];;
QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:crendential];
continueBlock(creator, nil);

}
}];
[[QCloudHTTPSessionManager shareClient] performRequest:request];
}
更多关于 iOS 如何向 COS 上传和下载文件,请参见 iOS SDK 快速入门

体验

Android

您可以单击 这里,或者使用 Android 手机浏览器 App,扫描下方二维码下载体验 demo:

完整的代码请参见:COS Android Demo

iOS

iOS 的完整示例工程请参见 COS iOS Demo
修改 QCloudCOSXMLDemo/QCloudCOSXMLDemo/key.json 文件,填入 APPID,secretID,secretKey 参数值,然后执行以下命令:
pod install
说明
APPID,secretID,secretKey 可前往 API 密钥管理 页面获取。
执行命令之后,打开 QCloudCOSXMLDemo.xcworkspace 即可进入 Demo 体验。

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈