OBS服務應用于互聯網數據上傳時 使用POST 實現服務端和客戶端權限控制和數據上傳分離的方法

      網友投稿 1041 2022-05-30

      1????? 背景

      采用JavaScript SDK 等客戶端直接簽名時,AccessKeyID和AcessKeySecret會暴露在前端頁面,因此存在嚴重的安全隱患。因此,OBS提供了服務端簽名后直傳的方案 解決此問題。問題代碼如下所示(需要在前端使用ak sk作為初始化條件):

      2????? 原理介紹

      1.???? 客戶端在登陸后,向app server請求上傳對象的鑒權token;

      2.???? App server 根據永久AK SK和針對上傳對象和桶的policy生成一個token(具體參考后的代碼示例)

      3.???? 前端組件 收到token后使用post請求將token作為一個表單項進行對象上傳。

      同時我們也做了示例網站進行功能的展示;https://codepen.io/x00403408/pen/xQYZgE 此地址示例如何生成一個token;

      https://codepen.io/x00403408/pen/WYMrbY 網站示例POST請求如何使用token進行數據的上傳

      2.1.2??????? 約束限制

      1.???? Post表單上傳是單流上傳,沒法實現斷點續傳功能。因此比較適合一些小文件的上傳。

      2.???? Post上傳對于表單域我們采用強校驗模式,只要攜帶的表單域除我們沒定義的外都要包含在policy中參與簽名計算。具體參考文檔描述:https://support.huaweicloud.com/api-obs/zh-cn_topic_0106557184.html

      3????? 流程和源碼解析

      3.1????? 服務端代碼

      Java SDK 代碼示例生成服務端token

      package?samples_java; ? import?java.io.File; import?java.io.IOException; import?java.util.ArrayList; ? import?com.obs.services.ObsClient; import?com.obs.services.ObsConfiguration; import?com.obs.services.exception.ObsException; import?com.obs.services.model.AuthTypeEnum; import?com.obs.services.model.PostSignatureRequest; import?com.obs.services.model.PostSignatureResponse; ? public?class?TestPostObject?{ ????private?static?final?String?endPoint?=?"obs.myhwclouds.com"; ? ????private?static?final?String?ak?=?""; ? ????private?static?final?String?sk?=?""; ? ????private?static?ObsClient?obsClient; ? ????private?static?String?bucketName?=?""; ? ????private?static?AuthTypeEnum?authType?=?AuthTypeEnum.OBS; ? ????public?static?void?main(String[]?args)?throws?IOException?{ ????????ObsConfiguration?config?=?new?ObsConfiguration(); ????????config.setEndPoint(endPoint); ????????config.setAuthType(authType); ? ????????try?{ ????????????obsClient?=?new?ObsClient(ak,?sk,?config); ????????????//創建token ????????????PostSignatureRequest?request?=?new?PostSignatureRequest(); ????????????request.setExpires(3600); ????????????ArrayList?conditions?=?new?ArrayList(); ????????????//Condition可以根據不同業務頭域的需求進行增刪 ????????????conditions.add("[\"starts-with\",\"$content-type\",\"\"]"); ????????????conditions.add("[\"starts-with\",\"$key\",\"\"]"); ????????????conditions.add("{\"bucket\":\""+bucket+"\"}"); ????????????request.setConditions(conditions); ????????????PostSignatureResponse?response?=?obsClient.createPostSignature(request); ????????????String?Token?=?response.getToken(); ??????????? ????????}?catch?(Exception?ex)?{ ????????????if?(ex?instanceof?ObsException)?{ ????????????????ObsException?e?=?(ObsException)?ex; ????????????????System.out.println("Message:?"?+?e.getMessage()); ????????????}?else?{ ????????????????ex.printStackTrace(); ????????????} ????????}?finally?{ ????????????if?(obsClient?!=?null)?{ ????????????????try?{ ????????????????????obsClient.close(); ????????????????}?catch?(IOException?e)?{ ????????????????} ????????????} ????????} ????} ? }

      3.2????? 客戶端代碼

      客戶端的代碼在使用POST進行表單上傳時候直接構造POST請求,其中傳遞token等表單域信息即可(JS代碼);此處可以參考我們的web示例(https://codepen.io/x00403408/pen/WYMrbY)的代碼(截取部分關鍵代碼):

      $(window.document).ready(function()?{ ? ??$('#progressBar').hide(); ??$('#upload').click(function()?{ ????var?token?=?$.trim($('#token').val()); ????var?bucket?=?$.trim($('#bucket').val()); ????var?endpoint?=?$.trim($('#endpoint').val()); ? ????var?fileList?=?$('#inputFile')[0].files; ????if(token?===?''?||?bucket?===?''?||?endpoint?===?''?||?fileList.length?<=?0){ ??????window.alert('輸入有誤!'); ??????return; ????} ? ????if(isIpAddress(endpoint)){ ??????endpoint?+=?'/'?+?bucket; ????}else{ ??????endpoint?=?bucket?+?'.'?+?endpoint; ????} ????endpoint?=?'https://'?+?endpoint; ? ? ????var?xhr?=?new?XMLHttpRequest(); ????xhr.open('POST',?endpoint,?true); ????var?formData?=?new?FormData(); ????var?key?=?$.trim($('#key').val())?||?fileList[0].name; ????formData.append('key',?key); ????formData.append('token',?token); ????var?contentType?=?mimeTypes[key.substring(key.lastIndexOf('.')?+?1)]; ????//if(contentType){ ???????????//formData.append('content-type',?contentType); ????//} ????//var?tokens?=?token.split(':'); ????//formData.append('AccessKeyId',?tokens[0]); ????//formData.append('Signature',?tokens[1]); ????//formData.append('Policy',?tokens[2]); ????formData.append('file',?fileList[0]); ? ? ????var?start?=?new?Date().getTime(); ????var?cost; ? ????xhr.upload.addEventListener('progress',?function(event)?{ ??????if?(event.lengthComputable)?{ ????????if(!cost){ ??????????$('#progressBar').show(); ????????} ????????cost?=?new?Date().getTime()?-?start; ????????var?uploadSpeed?=?(event.loaded?/?1024?/?cost?*?1000).toFixed(2)?+?'KB\/s'; ????????var?percentage?=?Math.round(event.loaded?*?100?/?event.total)?+?'%'; ????????$('#uploadSpeed').html(uploadSpeed); ????????$('#percentage').html(percentage); ????????$('#progressBar').css('width',?percentage); ??????} ????},?false); ? ????xhr.onreadystatechange?=?function(response)?{ ??????if(xhr.readyState?===?4){ ????????if(xhr.status?

      3.3????? 過程問題說明

      3.3.1??????? POST 上傳對應響應碼200或204對兼容性影響說明

      POST 上傳默認的響應碼是204,但是在IE8/9瀏覽器對此響應碼是不做狀態上報的,導致web中的JS代碼無法獲取什么時候上傳成功。際上是可以通過 success_action_status 重新定義響應狀態碼,在Post請求時候需要攜帶此項到表單域中。(POLICY中:["starts-with", "$success_action_status", ""],)

      請求示例:

      響應示例:

      3.3.2??????? 文件的content-type設置

      因為 在web/app類應用中為了防止不同用戶上傳的圖片產生重名問題,客戶在上傳時候會針對原始文件名稱生成一個唯一的對象名稱KEY值,這樣防止了存儲在對象存儲時候對象名稱相同時候覆蓋。

      OBS服務應用于互聯網數據上傳時 使用POST 實現服務端和客戶端權限控制和數據上傳分離的方法

      而這個時候導致一個問題,存儲在對象存儲的文件缺失了后綴名,JS-sdk不會增加content-type描述(通過后綴名增加)。OBS對于POST中攜帶默認的content-type描述不識別,導致設置為application/octect-stream;使得在瀏覽器下載時候不能在線展示;

      那么這個時候處理需要在前端上傳時候增加content-type表單域;同時在后端生成上傳token時policy也需要增加(POLICY中:["starts-with", "$ content-type ", ""],)來支持前端上傳。

      OBS

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:UWP 手繪視頻創作工具技術分享系列 - Ink & Surface Dial
      下一篇:《考取HCIA證書,看我就夠了》系列第一篇-華為職業認證體系及HCIA介紹
      相關文章
      久久亚洲国产精品五月天婷| 亚洲av色香蕉一区二区三区蜜桃| 亚洲av无码专区在线观看下载| 亚洲欧洲精品久久| 亚洲男人天堂2017| 亚洲bt加勒比一区二区| 亚洲AV无码久久精品狠狠爱浪潮 | 国产亚洲精品成人AA片新蒲金 | 亚洲欧洲自拍拍偷综合| 亚洲美女视频一区| 亚洲精品高清国产麻豆专区| 666精品国产精品亚洲| 亚洲黄色在线观看视频| 久久久久亚洲av无码专区| 18gay台湾男同亚洲男同| 亚洲视频免费观看| 亚洲精品在线不卡| 亚洲AV一二三区成人影片| 国产亚洲国产bv网站在线| 亚洲综合av一区二区三区不卡 | 中文字幕亚洲精品无码| 亚洲狠狠色丁香婷婷综合| 豆国产96在线|亚洲| 亚洲国产精品激情在线观看| 亚洲精品国产高清嫩草影院| 久久亚洲AV无码西西人体| 亚洲人成精品久久久久| 久久亚洲精品成人777大小说| 亚洲av午夜福利精品一区| 久久久久亚洲av无码专区导航| 亚洲精品在线免费看| 亚洲AV成人一区二区三区在线看| 亚洲精品欧美综合四区| 亚洲AV无码专区日韩| 青青草原亚洲视频| 亚洲AV美女一区二区三区| 亚洲视频一区在线| 伊人久久亚洲综合影院首页| 久久精品国产亚洲AV未满十八| 亚洲精品第一国产综合精品99| 亚洲免费观看视频|