閱讀283 返回首頁    go 阿裏雲


快速搭建移動應用直傳服務__移動應用端直傳實踐_最佳實踐_對象存儲 OSS-阿裏雲

本教程幫助您在30分鍾內搭建一個基於OSS的移動應用數據直傳服務。所謂直傳就是移動應用的數據的上傳和下載直接連接OSS,隻有控製流走用戶自己的服務器。

背景

這是一個移動互聯的時代,手機APP上傳的數據越來越多。把數據存儲的問題交給OSS,能夠讓開發者更加專注於自己的應用邏輯。

優勢

搭建一個基於OSS的移動應用數據直傳服務,具有以下優勢:

  • 安全的上傳下載方式(臨時、靈活的賦權鑒權)
  • 成本低(用戶不需要準備很多服務器,因為移動應用直聯雲存儲,隻有控製流走用戶自己的應用服務器)
  • 高並發,支持海量用戶(OSS有海量的上傳和下載帶寬)
  • 彈性(OSS有無限擴容的存儲空間)
  • 方便(可以方便的對接到媒體轉碼服務-視頻多端適配,圖片處理服務,CDN加速下載等)

架構圖


詳細可以參考這裏

角色解析

  • Android/iOS 移動應用,即最終用戶手機上的APP。
  • OSS,即阿裏雲對象存儲,負責存儲APP上傳的數據,可以參考官網介紹
  • RAM/STS負責生成臨時上傳憑證。
  • 用戶應用服務器,即提供該Android/iOS應用的開發者開發的APP後台服務,管理APP上傳和下載的Token,以及用戶在APP上傳數據的元數據信息。

數據流解析

  1. 應用向用戶的應用服務器申請一個臨時上傳憑證。
    Android/iOS應用不可能直接存儲AccessKeyID/AccessKeySecret,這樣會存在泄密的風險。所以應用必須向用戶的應用服務器申請一個臨時上傳憑證(下文將此臨時上傳憑證稱為Token),注意這個Token是有時效性的,如這個Token的過期時間是30分鍾(這個時間可以由應用服務器指定),那麼在這30分鍾裏麵,該Android/iOS應用可以使用這個Token從OSS上傳和下載數據, 30分鍾後再重新獲取。
  2. 用戶的應用服務器檢測上述請求的合法性,然後返回Token給應用。
  3. 手機拿到這個Token後就可以將數據上傳到OSS,或者從OSS下載數據了。

本教程主要介紹下述紅色和藍色框的內容。

  • 藍色框:應用服務器如何生成這個Token
  • 紅色框: Android/iOS應用如何獲取Token

效果

本教程實現了一個APP,如下圖所示。您可以掃描二維碼,安裝示例APP程序。此工具是用Android開發的,但是本教程的應用服務器搭建(即上述圖藍色框的內容)也適用於iOS。

示例程序的體驗

示例程序的最終效果圖如下:

  • 應用服務器:該移動應用對應的後台應用服務器。本教程搭建了一個後台應用服務器:https://oss-demo.aliyuncs.com/app-server/sts.php
  • 上傳Bucket:指的是該移動應用要把數據上傳到哪個Bucket。

  • 區域:指的是上傳Bucket對應的區域。

示例APP的使用

單擊選擇圖片,然後把文件上傳到OSS。上傳的方法支持普通上傳和斷點上傳。注意在一些網絡環境差的環境下,最好用斷點上傳。然後可以利用圖片處理服務,對將要上傳的圖片進行縮略和加水印處理。初始使用請暫時先不要更改應用服務器地址和Bucket名字。

準備工作

搭建這樣一個APP上傳和下載的係統,需要完成以下準備工作:

  1. 開通OSS,並且創建Bucket,在這個例子裏麵的,對應的Bucket是:sdk-demo。創建Bucket的操作請參見 這裏
  2. 開通STS服務。開通STS服務是為了生成上述所描述的Token。具體請參見以下“為帳號開通STS服務”。
  3. 搭建一個應用服務器。這在個例子裏,搭建的應用服務器的地址是:https://oss-demo.aliyuncs.com/app-server/sts.php

    注意:這個例子是采用PHP編寫的,用戶也可以選擇自己喜歡的語言進行編寫,如Java 、Python、 Go、Ruby、Node.js、C#等。

為帳號開通STS服務

  1. 登錄 OSS管理控製台

  2. 單擊 安全令牌 快捷配置。

  3. 進入到 安全令牌快捷配置 頁麵,注意如果沒有開通RAM,會彈出開通的對話框。直接單擊 開通,並進行實名驗證。做完後跳到本頁麵。單擊 開始授權

  4. 係統進行自動授權,請務必保存下圖中三個紅框內的參數。


    單擊保存AK信息後,對話框會關閉。保存好下麵紅框中的結果3.

    保存這三個參數後,STS的開通已經完成了。
    注意如果您之前已經點擊這個頁麵創建了AccessKeyId/AccessKeySecret, 彈出的頁麵如下:


    單擊如下圖所示的查看


    單擊如下圖所示的創建AccessKey


    記下如下參數1、2。

    並記下如下參數3。

    保存這三個參數後,STS的開通已經完成了。

應用服務器代碼示例的下載

為了方便開發,本教程提供了三個語言的版本示例程序供您下載。

應用服務器示例的配置

每個語言包下載下來後,都會有一個配置文件config.json如下例:

  1. {
  2. "AccessKeyID" : "",
  3. "AccessKeySecret" : "",
  4. "RoleArn" : "",
  5. "TokenExpireTime" : "900",
  6. "PolicyFile": "policy/all_policy.txt"
  7. }

下麵對配置進行講解:

  1. AccessKeyID: 填寫上述圖標紅的參數1的內容。
  2. AccessKeySecret: 填寫上述圖標紅的參數2的內容。
  3. RoleArn: 填寫上述圖標紅的參數3的內容。
  4. TokenExpireTime: 指Android/iOS應用取到這個Token的失效時間,注意,最少是900s,默認值可以不修改。
  5. PolicyFile: 填寫的是該Token所要擁有的權限列表的文件, 默認值可以不修改。
    本教程準備了三種最常用token 權限文件,放於policy目錄下麵。分別是:
    • all_policy.txt:指定了該token擁有對該帳號下創建Bucket、刪除Bucket、上傳文件、下載文件、刪除文件的權限 。
    • bucket_read_policy.txt:指定了該token擁有該帳號下對指定Bucket的讀權限。
    • bucket_read_write_policy.txt: 指定了該token擁有該帳號下對指定Bucket的讀寫權限。
      如果你想要指定這個Token隻能對指定的bucket有讀寫權限, 請把(bucket_read_policy.txt、 bucket_read_write_policy.txt)這個文件裏麵$BUCKET_NAME直接替換成指定的bucket名字。

返回的格式解析:

  1. {
  2. "status":200,
  3. "AccessKeyId":"STS.3pYjsdgdgagdasdg",
  4. "AccessKeySecret":"rpnwO9kvEgetGdrddgsR2YrTtI",
  5. "Security":"CAES+wMIARKAAZhjH0EUOIhJMQBMjRywXq7MQ/cjLYg80Aho1ek0Jm63XMhr9Oc5s˙∂˙∂3qaPer8p1YaX1NTDiCFZWFkvlHf1pQhuxfKBc+mRR9KAbHUefqH+rdjZqjTF7p2m1wJXP8S6k+G2MpHrUe6TYBkJ43GhhTVFMuM3BZajY3VjZWOXBIODRIR1FKZjIiEjMzMzE0MjY0NzM5MTE4NjkxMSoLY2xpZGSSDgSDGAGESGTETqOio6c2RrLWRlbW8vKgoUYWNzOm9zczoqOio6c2RrLWRlbW9KEDExNDg5MzAxMDcyNDY4MThSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzMzMTQyNjQ3MzkxMTg2OTExcglzZGstZGVtbzI=",
  6. "Expiration":"2015-12-12T07:49:09Z",
  7. }
  • status:表示獲取Token的狀態,獲取成功時,返回值是200。
  • AccessKeyId: 表示Android/iOS應用初始化OSSClient獲取的 AccessKeyId。
  • AccessKeySecret: 表示Android/iOS應用初始化OSSClient獲取AccessKeySecret。
  • SecurityToken:表示Android/iOS應用初始化的Token。
  • Expiration: 表示該Token失效的時間。主要在Android SDK會自動判斷是否失效,自動獲取Token。注意上述這四個變量將構成了一個Token。

代碼示例的運行方法

  • 對於PHP版本,將包下載解壓後,修改config.json這個文件,直接運行php sts.php 即能生成Token,將程序部署到指定的地址。
  • 對於JAVA版本 (依賴於java 1.7),將包下載解壓後,運行方法:java -jar oss-token-server.jar (port)。如果不指定port(端口), 直接運行java –jar oss-token-server.jar,程序會監聽7080端口。如果想讓程序執行在9000端口,運行java –jar oss-token-server.jar 9000 , 其他端口也類似。

體驗自己的APP上傳應用服務器

  1. 把程序部署起來後,記下應用服務器地址如https://abc.com:8080 將示例程序裏麵的應用服務器修改成上述地址。
  2. 選擇自己數據要上傳到哪個Bcuket及區域,修改示例APP程序裏麵相應Bucket及區域。
  3. 單擊設置按鈕,將配置加載。
  4. 選擇圖片,設置上傳OSS文件名,上傳。然後就可以在Android上體驗OSS服務了。這樣你就能通Android 示例程序將數據直接上傳到OSS了。
  5. 上傳成功後,可以看一下數據是否在OSS上了。

核心代碼解析:OSS初始化

下麵講解如何利用Android/iOS SDK跟自己的應用服務器,請求Token。

  • Android版本
  1. //初始化一個OssService用來上傳
  2. public OssService initOSS(String endpoint, String bucket, UIDisplayer displayer) {
  3. OSSCredentialProvider credentialProvider;
  4. //使用自己的獲取STSToken的類
  5. //從應用服務器控件裏麵讀取應用服務器地址
  6. String stsServer = ((EditText) findViewById(R.id.stsserver)).getText().toString();
  7. //STSGetter類,封裝如何跟從應用服務器取數據,必須繼承於OSSFederationCredentialProvider這個類。 取Token這個取決於你所寫的APP跟應用服務器數據的協議設計。
  8. if (stsServer .equals("")) {
  9. credentialProvider = new STSGetter();
  10. }else {
  11. credentialProvider = new STSGetter(stsServer);
  12. }
  13. //獲取控件上的bucket名字
  14. bucket = ((EditText) findViewById(R.id.bucketname)).getText().toString();
  15. //初始化OSSClient
  16. ClientConfiguration conf = new ClientConfiguration();
  17. conf.setConnectionTimeout(15 * 1000); // 連接超時,默認15秒
  18. conf.setSocketTimeout(15 * 1000); // socket超時,默認15秒
  19. conf.setMaxConcurrentRequest(5); // 最大並發請求書,默認5個
  20. conf.setMaxErrorRetry(2); // 失敗後最大重試次數,默認2次
  21. OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);
  22. return new OssService(oss, bucket, displayer);
  23. }
  • iOS版本
  1. // 初始化一個OSSClient實例
  2. - (void)ossInit {
  3. // 構造一個獲取STSToken的憑證提供器
  4. id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
  5. // 實現一個函數,同步返回從server獲取到的STSToken
  6. return [self getFederationToken];
  7. }];
  8. // 用endpoint、憑證提供器初始化一個OSSClient
  9. client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential];
  10. }

核心代碼解析:移動應用從應用服務器取Token

具體APP從應用服務器取Token的方法,必須寫到public OSSFederationToken getFederationToken() { }這個函數裏麵。注意這個函數的邏輯依賴於可以自己設定,但是最終結果必須返回這樣一個變量 return new OSSFederationToken(ak, sk, token, expiration),其中ak, sk, token, expiration 必須是從應用服務器返回的Body獲取的。

在本例子裏,示例如下。注意用戶可以自定義自己的移動應用跟自己應用服務器之前的協議。

  • Android版本
  1. public OSSFederationToken getFederationToken() {
  2. String stsJson;
  3. OkHttpClient client = new OkHttpClient();
  4. Request request = new Request.Builder().url(stsServer).build();
  5. try {
  6. Response response = client.newCall(request).execute();
  7. if (response.isSuccessful()) {
  8. stsJson = response.body().string();
  9. } else {
  10. throw new IOException("Unexpected code " + response);
  11. }
  12. }
  13. catch (IOException e) {
  14. e.printStackTrace();
  15. Log.e("GetSTSTokenFail", e.toString());
  16. return null;
  17. }
  18. try {
  19. JSONObject jsonObjs = new JSONObject(stsJson);
  20. String ak = jsonObjs.getString("AccessKeyId");
  21. String sk = jsonObjs.getString("AccessKeySecret");
  22. String token = jsonObjs.getString("SecurityToken");
  23. String expiration = jsonObjs.getString("Expiration");
  24. return new OSSFederationToken(ak, sk, token, expiration);
  25. }
  26. catch (JSONException e) {
  27. Log.e("GetSTSTokenFail", e.toString());
  28. e.printStackTrace();
  29. return null;
  30. }}
  • iOS版本
  1. NSURL * url = [NSURL URLWithString:STSServer];
  2. NSURLRequest * request = [NSURLRequest requestWithURL:url];
  3. OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource];
  4. NSURLSession * session = [NSURLSession sharedSession];
  5. NSURLSessionTask * sessionTask = [session dataTaskWithRequest:request
  6. completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  7. if (error) {
  8. [tcs setError:error];
  9. return;
  10. }
  11. [tcs setResult:data];
  12. }];
  13. [sessionTask resume];
  14. // 實現這個回調需要同步返回Token,所以要waitUntilFinished
  15. [tcs.task waitUntilFinished];
  16. if (tcs.task.error) {
  17. // 如果網絡請求出錯,返回nil表示無法獲取到Token。該次請求OSS會失敗。
  18. return nil;
  19. } else {
  20. // 從網絡請求返回的內容中解析JSON串拿到Token的各個字段,組成STSToken返回
  21. NSDictionary * object = [NSJSONSerialization JSONObjectWithData:tcs.task.result
  22. options:kNilOptions
  23. error:nil];
  24. OSSFederationToken * token = [OSSFederationToken new];ni
  25. token.tAccessKey = [object objectForKey:@"AccessKeyId"];
  26. token.tSecretKey = [object objectForKey:@"AccessKeySecret"];
  27. token.tToken = [object objectForKey:@"SecurityToken"];
  28. token.expirationTimeInGMTFormat = [object objectForKey:@"Expiration"];
  29. return token;
  30. }

示例程序的實現

應用服務器代碼示例的下載

最後更新:2016-11-23 16:04:09

  上一篇:go 雲端數據處理__開發人員指南_對象存儲 OSS-阿裏雲
  下一篇:go 權限控製__移動應用端直傳實踐_最佳實踐_對象存儲 OSS-阿裏雲