本文講解如何搭建一個基於OSS的行動裝置 App資料直傳服務並設定上傳回調。
背景資訊
快速搭建行動裝置 App直傳服務介紹了如何快速搭建一個基於OSS的行動裝置 App資料直傳服務。但該方案有個問題:對於Android/iOS行動裝置 App來說,只需要申請一次STS憑證,就能多次使用該STS憑證上傳資料到OSS。這就導致應用伺服器無法得知使用者上傳了哪些資料 ,作為該App的開發人員,就無法對應用上傳資料進行管理。為此OSS提供了上傳回調方案。
流程介紹
上傳回調的開發流程如下:
OSS在收到Android/iOS行動裝置 App的資料(上圖中步驟5)和在返回使用者上傳結果(上圖中步驟7)之間,觸發一個上傳回調任務,即第上圖中步驟6,通過回調使用者服務器擷取應用伺服器返回的內容,然後將此內容返回給Android/iOS行動裝置 App。詳情請參見Callback API文檔。
上傳回調的作用
通過上傳回調讓使用者應用伺服器知道當前上傳檔案的基本資料。
返回的基本資料可以包含下表中一個或多個變數,返回內容的格式在Android/iOS上傳時指定。
系統變數
含義
bucket
行動裝置 App上傳檔案到OSS的哪個儲存空間
object
行動裝置 App上傳檔案到OSS後儲存的檔案名稱
etag
該上傳的檔案的ETag,即返回給使用者的etag欄位
size
上傳檔案的大小
mimeType
資源類型
imageInfo.height
圖片高度
imageInfo.width
圖片寬度
imageInfo.format
圖片格式,如JPG、PNG等
通過上傳回調設定自訂參數,達到資訊傳遞的目的。
假如您是一個開發人員,您想知道目前使用者所使用的App版本、目前使用者所在的作業系統版本、使用者的GPS資訊、使用者的手機型號。您可以在Android/iOS端上傳檔案時,指定以下自訂參數:
x:version:指定App版本
x:system:指定作業系統版本
x:gps:指定GPS資訊
x:phone:指定手機型號
Android/iOS行動裝置 App上傳檔案到OSS時附帶上述參數,然後OSS把這些參數放到CallbackBody裡發給應用伺服器。這樣應用伺服器就能收到這些資訊,達到資訊傳遞的目的。
上傳回調對應用伺服器的要求
部署一個可以接收POST請求的服務,這個服務必須有公網地址,例如
http://example.com/callback.php
。您必須給OSS正確的返回,返回格式必須是JSON格式,內容自訂。OSS會把應用伺服器返回的內容再返回給Android/iOS行動裝置 App。詳情請參見Callback API文檔。
在行動裝置 App端設定上傳回調
要讓OSS在接收上傳請求時觸發上傳回調,行動裝置 App在構造上傳請求時必須把如下內容指定到上傳請求裡面:
要回調到哪個伺服器(callbackUrl),例如
http://example.com/callback.php
,這個地址必須是公網能夠訪問的。上傳回調給應用伺服器的內容(callbackBody),可以是上述OSS返回應用伺服器系統變數的一個或者多個。
假如您的使用者服務器上傳回調地址是http://example.com/callback.php
。您想擷取手機上傳的檔案名稱、檔案的大小,並且定義了x:phone變數是指手機型號,x:system變數是指作業系統版本。
上傳回調樣本分以下兩種:
iOS指定上傳回調樣本:
OSSPutObjectRequest * request = [OSSPutObjectRequest new]; request.bucketName = @"<bucketName>"; request.objectKey = @"<objectKey>"; request.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"]; // 設定回調參數 request.callbackParam = @{ @"callbackUrl": @"http://example.com/callback.php", @"callbackBody": @"filename=${object}&size=${size}&phone=${x:phone}&system=${x:system}" }; // 設定自訂變數 request.callbackVar = @{ @"x:phone": @"iphone6s", @"x:system": @"ios9.1" };
Android指定上傳回調樣本:
PutObjectRequest put = new PutObjectRequest(testBucket, testObject, uploadFilePath); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("application/octet-stream"); put.setMetadata(metadata); put.setCallbackParam(new HashMap<String, String>() { { put("callbackUrl", "http://example.com/callback.php"); put("callbackBody", "filename=${object}&size=${size}&phone=${x:phone}&system=${x:system}"); } }); put.setCallbackVars(new HashMap<String, String>() { { put("x:phone", "iPhone 6s"); put("x:system", "YunOS5.0"); } });
應用伺服器收到的回調請求
根據設定的不同URL和回調內容,應用伺服器收到的回調請求會有所不同,樣本如下:
POST /index.html HTTP/1.0
Host: 203.0.113.0
Connection: close
Content-Length: 81
Content-Type: application/x-www-form-urlencoded
User-Agent: ehttp-client/0.0.1
authorization: kKQe**************/kdD1ktNVgbWE**************
x-oss-pub-key-url: aHR0**************
filename=test.txt&size=5&phone=iphone6s&system=ios9.1
更多內容請參見Callback API文檔。
應用伺服器判斷回調請求是否來自OSS
如果您的回調伺服器被人惡意攻擊了,例如惡意回調您的應用伺服器,導致應用伺服器收到一些非法的請求,影響正常邏輯,此時您就需要判斷回調請求是否來自OSS。
判斷的方法主要是根據OSS給應用伺服器返回的頭部內容中 x-oss-pub-key-url
和authorization
這兩個參數進行RSA校正。只有通過RSA校正才能說明這個請求是來自OSS。本文提供的樣本程式有實現的樣本供您參考。
應用伺服器收到回調請求後的處理
應用伺服器在校正這個請求是來自OSS後,指定回調給應用伺服器的內容格式,如
filename=test.txt&size=5&phone=iphone6s&system=ios9.1
應用伺服器就可以根據OSS的返回內容,解析得到自己想要的資料。得到這個資料後,應用伺服器可以把資料存放起來,方便後續管理。
OSS如何處理應用伺服器的返回內容
有兩種情況:
OSS將回調請求發送給應用伺服器,但是應用伺服器接收失敗或者訪問不通,OSS會返回給Android/iOS行動裝置 App203的狀態代碼,但是資料已經存放到OSS上了。
應用伺服器接收到OSS的回調請求,並且正確返回了,OSS會返回給Android/iOS行動裝置 App狀態代碼200,並把應用伺服器返回給OSS的內容返回給Android/iOS行動裝置 App。
樣本程式下載
樣本程式只是完成了如何檢查應用伺服器收到的簽名, 您需要自行增加對應用伺服器收到回調內容的格式解析 。
Java
下載地址。
運行方法:解壓後運行java -jar oss-callback-server-demo.jar 9000。9000是啟動並執行連接埠,可以自己指定。
說明這個JAR例子在Java 1.7運行通過,如果有問題請依據提供的代碼自行修改。這是一個Maven專案。
PHP
下載地址。
運行方法:將解壓包部署到Apache環境下,因為PHP本身語言的特點,某些資料頭部的擷取會依賴於環境。請參考例子根據實際環境進行修改。
Python
下載地址。
運行方法:解壓後直接運行python callback_app_server.py即可,程式自實現了一個簡單的HTTP Server,運行該程式可能需要安裝RSA的依賴。
Ruby版本
下載地址。
運行方法: 運行ruby server.rb。
常見問題
callback地址是否可以篡改成其他地址,由其他伺服器接收回調並確認上傳成功與否?
不可以篡改成其他地址,因為參數會被簽名被OSS服務端驗證,而篡改的內容無法通過驗證。