記一次前端適配后台接口改造的開發小結


在最近工作中,有因后台接口升級,前端需要配合改造的需求。在改造適配過程中,遇到了問題,再經過多次折騰后,最終調通。事后再回顧整個調試過程,覺的之前走過一些彎路,在回顧時才看的更加真切,在此需要總結歸納。

問題背景

先描述下問題背景,為簡化后續討論,后續以"查產品信息"和"查資金"兩個接口為例子,后台對這兩個接口有升級,具體包括

  • "查產品信息"接口,優化內部實現,認證方式是參數簽名。
  • "查資金"接口升級,接口出入參沒變,認證方式改為授權碼,該授權碼由另一個認證服務提供,不同服務的授權碼不一樣。

問題描述

舊版本的流程如下:

舊版本交互示意圖.jpg

前端沒有關心參數簽名細節,將參數一股腦傳給中轉服務,由中轉服務完成對簽名操作,並將簽名值附加在請求最后。

該中轉服務是其他同事負責的,前端沒有關心細節。

后台改造升級,新的流程如下:

新版本交互示意圖.jpg

針對"查資金"接口,需要先向認證服務獲取認證碼,該認證碼的權限很大,為了安全起見,獲取認證碼的操作放到中轉服務中。這個中轉服務是新寫的,考慮到兼容對參數簽名接入的兼容,對請求參數進行簽名的職責交給前端。

按照上面新流程進行開發,很順利。到聯調階段,發現走參數簽名的方法總是失敗,返回“簽名不通過”的問題。

問題分析流程

根據接口文檔的描述,參數簽名的接入需要送兩個特殊的參數:

  • RandomKey: 由登陸相關參數拼接而成
  • AppKey :由所有url請求參數按照指定規則拼接而成

舊版本的這兩個參數是有中轉服務來拼接,新版改為前端拼接,這里最初遺漏了對AppKey的處理,后來在新中轉服務中,參照舊版實現,補充對AppKey的處理,發現還是返回“簽名不通過”,這就奇怪了。

在調試遇到阻礙,無法進行下去時,通過詢問同事以及舊模塊的維護人員,靜下心來分析,

舊版本是正常的,新版本返回簽名不通過,新舊版本對接同一個第三方服務,那唯一的可能是新舊版本請求串不一樣。

對比新舊請求url的異同,終於發現突破點,可能是 RandomKey 的問題。

新版本:RandomKey=inputtype%3dC%26inputid%3d123456%26custorgid%3d1000%26orgid%3d1100%26tradenode%3d9501%26ext1%3d0000%26userinfo%3d~~~1100%26authid%ABCDEFD

舊版本:RandomKey=authid%ABCDEFD%26custorgid%3D1000%26ext1%3D1000%26inputid%3D123456%26inputtype%3DC%26orgid%3D1100%26tradenode%3D9501%26userinfo%3D~~~1100

經過對比發現,新舊版本的RandomKey中構成元素是一樣的,唯一區別在於順序。舊版本是按照字母序進行排列,新版本是按照接口文檔規定的順序排列。

為什么按照接口文檔規定的順序無法訪問,按照字母序可以訪問呢?舊版本中對random進行字母序排列的依據是什么?帶着這些疑問,進一步詢問相關人員,發現三個問題:

  • 接口文檔中對randomkey中順序沒有明確要求,但在驗證時隱含了此要求
  • 舊的實現對第三方接口隱含的缺陷進行了兼容處理,而沒有對此兼容處理做顯式說明,導致后續維護人員踩入同樣的坑
  • 舊的實現在對接口簽名時,有一些和前端的約定,比如編碼是由哪一方來做,順序是有哪一方來保證

問題解決方案

分析得到問題根源后,順藤摸瓜,解決方案也就出來了。由前端或者中轉服務來對Random進行處理,為了后續的靈活性,此處由中轉服務來處理,前端無需關系。

知識點梳理

url編碼知識

url標准規定,url采用ASCII碼,RFC3986文檔規定:Url中只允許[0-9a-zA-Z]、“-_.~”4個特殊字符以及所有保留字符(用於分隔不同組件),每個特殊符號有特定含義:

  • 冒號":"用於分隔協議和主機
  • "/"號用於分隔主機和路徑
  • "?"用於分隔路徑和入參
  • "="用於鍵值對區分
  • "&"區分多個鍵值對

如遇到不安全的字符,使用安全字符來代替。例如中文,上述特殊字符。

為了不對內容有依賴,在拼接url時,需要對pathkeyvalue進行utf8編碼(解決中文傳輸問題),再對進行url編碼(解決key或value中有可能包含URL特殊符號,引起后端解析錯誤)。

base64編碼

base64是將非ASCII數據轉換為ASCII數據的一種方法,編解碼速度快,目的是:

  1. 兼容某些只能處理ASCII字符的系統。
  2. 解決傳輸設備(路由器、交換機)對不可見字符處理不一致而引發的問題
  3. 簡單加密方式

有些Base64編碼方案中包含url中的"+/="字符,采用這種方案,需要先進行base64編碼,再進行url編碼。
如果是針對Url特殊字符改進版的Base64編碼,可不考慮先后順序。

瀏覽器請求

以chrome為例子,當url請求中帶有中文時,例如: “https://baike.baidu.com/item/春節/136876?fr=aladdin” 實際送的是"https://baike.baidu.com/item/春節/136876?fr=aladdin",其中,"春節"兩字的先進行utf8編碼,然后進行url編碼。

對url中的key和value也是同樣的處理方式。

小結

通過本次調試過程的梳理,有以下幾點經驗和思考:

  1. 后端在對接第三方服務時,要是發現接口描述不清,在經過溝通后發現需要特殊處理才能跑通,一定要敦促他們完善接口文檔,這是最佳選擇。
  2. 后端在遇到需要特殊處理的地方,要將處理依據以及對接人,明確寫在注釋以及提交記錄上,讓后續維護者了解此處的坑。
  3. 當前端在承接一些后台職責時,光看接口文檔時是不夠的,有時候后台會對接口中的缺陷進行隱含處理,錯錯得正,給前端造成一種錯覺,覺的按照接口文檔來,那就一定沒問題的。
  4. 前后端聯合開發時,一定要划分清楚職責並如實記錄,哪里負責編碼,哪些負責附加字段等問題,要在概要設計時,就明確下來。
  5. 編碼問題,不能依着結果是一致就不去編碼,面向邏輯開發,而不是結果開發。不能因為簡單的幾個例子跑對了,就不去管邏輯上可能的遺漏。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM