腾讯云对象存储移动应用直传

移动应用直传腾讯云对象存储简介

本文主要介绍基于腾讯云对象存储腾讯云对象存储,如何实现移动应用直传至腾讯云对象存储。作为移动APP开发者,你可以利用腾讯云对象存储处理各种数据的存储及分发需求,从而更加专注于自己的应用逻辑。

基于腾讯云对象存储的移动应用数据直传服务具有以下优势:

  • 数据安全:使用灵活的预签名URL进行数据的上传和下载,更加安全;
  • 成本低廉:数据不需要由APPServer中转;移动APP直接连接腾讯云对象存储,只有控制流连接应用服务器;
  • 弹性扩容:无限扩容的存储空间;
  • 数据处理:和图片处理以及音视频转码搭配使用,方便灵活地进行数据处理;

原理介绍

对于客户端应用,把访问密钥放到客户端代码中,这既容易泄露你的密钥信息,也不便于控制用户访问权限。通过预签名URL,你可以临时授权你的App访问你的存储资源,而不会泄露你的访问密钥。

预签名URL简介:

默认情况下,所有的对象和存储桶都是私有的。如果你希望你的用户能够将特定对象上传到你的存储桶,但不希望他们使用你的访问秘钥,则可以使用预签名URL。创建预签名URL时,你可以指定存储桶名称、对象名称、HTTP方法(如执行PUT操作)和有效期。身份验证信息将以查询字符串参数的形式提供,超出有效期后该预签名URL将失效。

流程说明:

  • 1.移动应用向应用服务器请求预签名URL;

  • 2.应用服务器生成预签名URL,并返回给移动应用客户端;

  • 3.移动应用使用预签名URL将文件上传至腾讯云对象存储;

  • 4.传输完成后,腾讯云对象存储返回上传成功消息;

  • 5.若用户配置了上传回调通知,则腾讯云对象存储会异步回调应用服务器;

  • 6.应用服务器收到回调消息后返回回调成功消息。

应用服务器示例代码

你可以在应用服务器上部署以下示例代码用于生成预签名URL,你可以根据你的业务逻辑调整该示例代码。移动应用在请求腾讯云对象存储前,可请求应用服务器返回预签名URL,需根据腾讯云对象存储访问需求传入预签名的相关参数(如Bucket、Key、HTTPMethod等)。

本示例基于S3JAVASDK编写,SDK安装与使用可参考JAVASDK安装。

importjava.net.URL;importjava.util.Date;importcom.amazonaws.ClientConfiguration;importcom.amazonaws.HttpMethod;importcom.amazonaws.Protocol;importcom.amazonaws.SDKGlobalConfiguration;importcom.amazonaws.auth.AWSCredentials;importcom.amazonaws.auth.BasicAWSCredentials;importcom.amazonaws.services.s3.AmazonS3;importcom.amazonaws.services.s3.AmazonS3Client;importcom.amazonaws.services.s3.S3ClientOptions;importcom.amazonaws.services.s3.model.GeneratePresignedUrlRequest;publicclassPresignUrl{staticAmazonS3createS3Client(StringaccessKey,StringsecretKey,Stringendpoint){System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY,"true");AWSCredentialsawsCredentials=newBasicAWSCredentials(accessKey,secretKey);ClientConfigurationconfig=newClientConfiguration();config.setProtocol(Protocol.HTTP);AmazonS3s3=newAmazonS3Client(awsCredentials,config);s3.setEndpoint(endpoint);S3ClientOptionsoptions=newS3ClientOptions();options.withChunkedEncodingDisabled(true);//Musthaves3.setS3ClientOptions(options);returns3;}staticpublicURLgeneratePresignUrl(StringaccessKey,StringsecretKey,Stringendpoint,StringbucketName,StringkeyName,HttpMethodmethod,Dateexpiration){AmazonS3s3=createS3Client(accessKey,secretKey,endpoint);GeneratePresignedUrlRequestrequest=newGeneratePresignedUrlRequest(bucketName,keyName).withMethod(method).withExpiration(expiration);returns3.generatePresignedUrl(request);}staticpublicvoidmain(String[]str){finalStringaccessKey="youraccessKey";finalStringsecretKey="yoursecretKey";finalStringendpoint="yourendpoint";finalStringbucketName="yourbucketname";finalStringkeyName="yourkeyname";finalHttpMethodmethod=HttpMethod.PUT;//此处设置你的PresignUrl允许的HTTP方法finalIntegerexpireInSeconds=100;//此处设置你的PresignUrl有效的时间段,以秒为单位finalDateexpiration=newDate(System.currentTimeMillis()+expireInSeconds1000);URLurl=generatePresignUrl(accessKey,secretKey,endpoint,bucketName,keyName,method,expiration);System.out.println("Pre-SignedURL:"+url);}}使用预签名URL

预签名URL生成完成后,应用服务器需将该URL返回给移动应用。移动应用可以使用该预签名URL访问腾讯云对象存储,该URL仅可在指定的有效期内使用,仅支持使用指定的HTTPMethod访问指定的资源(即生成预签名URL时指定的Method、Bucket、Key)。

预签名URL示例:

http://testbucket.s3.cn-north-1.jcloudcs.com/testkey?X-Amz-Algorithm=AWS4-HMAC-SHA256X-Amz-Date=20190117T061845ZX-Amz-SignedHeaders=hostX-Amz-Expires=98X-Amz-Credential=59E6DC72927457BDEBF36A56EE616B07%2F20190117%2Fcn-north-1%2Fs3%2Faws4_requestX-Amz-Signature=cc379e30731236473de05dcb7a3ad1b275fb0d6af58ecfdbd06e2dd051dd57ed

注:预签名URL不会暴露你的AccessKeySecret。

使用Curl命令模拟使用预签名URL上传文件,示例命令如下:

curl-XPUT-Ttestfile"http://testbucket.s3.cn-north-1.jcloudcs.com/testkey?X-Amz-Algorithm=AWS4-HMAC-SHA256X-Amz-Date=20190117T044444ZX-Amz-SignedHeaders=hostX-Amz-Expires=98X-Amz-Credential=59E6DC72927457BDEBF36A56EE616B07%2F20190117%2Fcn-north-1%2Fs3%2Faws4_requestX-Amz-Signature=a21204debab7c0b0c4ba334e6a9f76d5b6ce3328591acc29890540ddee513dcf"-v配置回调通知

由于移动应用上传数据时,并不通过应用服务器中转,而是直接传输至腾讯云对象存储。若应用服务器需要知道移动应用上传了哪些文件,可以通过配置回调通知功能实现。更多信息请参考回调通知,你可以指定存储桶资源变动时及时进行回调通知。

你可按照以下示例配置你的应用服务器作为回调服务器,当回调通知触发时,腾讯云对象存储将会向回调URL发起消息通知,事件消息为JSON格式,你可以从事件消息中解析你需要的内容。

importorg.springframework.http.HttpHeaders;importorg.springframework.util.Base64Utils;importorg.springframework.web.bind.annotation.;importjava.nio.charset.StandardCharsets;@RestControllerpublicclassSubscriptionTest{//简单格式的消息通知@RequestMapping("/notifications1")publicStringnotifications1(@RequestBodyStringmessage,@RequestHeaderHttpHeadersheaders){if(headers.get("x-jdcloud-message-type").get(0).equals("SubscriptionConfirmation")){//设置时对url的校验,需要对message进行base64编码并返回returnBase64Utils.encodeToString(message.getBytes(StandardCharsets.UTF_8));}else{//消息通知处理yourcode,处理完毕后需要返回httpcode200,body不做校验return"";}}}