忙了一天竟然在一個以前自認為,很基礎的問題上卡頓了,為了防止以后出現類似錯誤,決定還是記錄下來,順便整理下思路!
釘釘開發中有PC和移動之分,這個已經講過,其中最基礎也是最重要的當屬其中的簽名驗證了,也只有這個步驟成功了你才可以調取JSAPI文檔中的一些組件的接口。(不用釘釘組件的童鞋可以無視我這句 -。-)
其中PC版的簽名驗證算法如圖:
1 JS-API權限簽名算法 2 3 如果開發者想使用釘釘容器開放的jsapi接口,需要經過以下流程: 4 5 首先需要獲取jsapi_ticket。 6 然后在web頁面加載到釘釘容器時,通過jsapi權限驗證配置接口驗證可用的jsapi。這個接口使用的參數signature,在下文中有詳細的說明。 7 1.獲取jsapi_ticket 8 9 jsapi_ticket,是開發者調用釘釘JS接口的臨時授權碼,其作用主要用於生成簽名,這個簽名在jsapi權限驗證配置接口中使用。 10 11 正常的情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由於頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket。 12 13 獲取jsapi_ticket,具體可以參考文檔 14 15 2.簽名生成算法 16 17 開發者在web頁面使用釘釘容器提供的jsapi時,需要驗證調用權限,並以參數signature標識合法性 18 19 簽名生成的規則: 20 21 List keyArray = sort(noncestr,timestamp,jsapi_ticket,url); 22 23 String str = assemble(keyArray); 24 25 signature = sha1(str); 26 27 參與簽名的字段包括在上文中獲取的jsapi_ticket,noncestr(隨機字符串,自己隨便填寫即可),timestamp(當前時間戳,具體值為當前時間到1970年1月1號的秒數),url(當前網頁的URL,不包含#及其后面部分)。例如: 28 29 noncestr=Zn4zmLFKD0wzilzM 30 jsapi_ticket=mS5k98fdkdgDKxkXGEs8LORVREiweeWETE40P37wkidkfksDSKDJFD5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcKIDU8l 31 timestamp=1414588745 32 url=//open.dingtalk.com 33 步驟1. sort()含義為對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序) 34 35 步驟2. assemble()含義為根據步驟1中獲的參數字段的順序,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串 36 37 步驟2. sha1()的含義為對在步驟2拼接好的字符串進行sha1加密。
移動客戶端簽名驗證如下:
1 1.獲取jsapi_ticket 2 3 jsapi_ticket,是開發者調用釘釘JS接口的臨時授權碼,其作用主要用於生成簽名,這個簽名在jsapi權限驗證配置接口中使用。 4 5 正常的情況下,jsapi_ticket的有效期為7200秒,通過access_token(注意,假如您是ISV開發者,這個access_token需要企業授權的access_token接口)來獲取。由於頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket。 6 獲取jsapi_ticket,具體可以參考文檔) 7 8 2.簽名生成算法 9 10 開發者在web頁面使用釘釘容器提供的jsapi時,需要驗證調用權限,並以參數signature標識合法性 11 12 簽名生成的規則: 13 14 List keyArray = sort(noncestr,timestamp,jsapi_ticket,url); 15 16 String str = assemble(keyArray); 17 18 signature = sha1(str); 19 20 參與簽名的字段包括在上文中獲取的jsapi_ticket,noncestr(隨機字符串,自己隨便填寫即可),timestamp(當前時間戳,具體值為當前時間到1970年1月1號的秒數),url(當前網頁的URL,不包含#及其后面部分,需要對url中query部分做一次urldecode)。例如: 21 22 noncestr=Zn4zmLFKD0wzilzM 23 jsapi_ticket=mS5k98fdkdgDKxkXGEs8LORVREiweeWETE40P37wkidkfksDSKDJFD5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcKIDU8l 24 timestamp=1414588745 25 url=//open.dingtalk.com 26 注意:必須要對生成簽名的url的query部分做一次urldecode。例如,如果你的url是http://abc.com?url=http%3A%2F%2Fabc.com%2somewhere,那么你在生成簽名的時候用到的url應該是對原url做過decode的url,即http://abc.com?url=http://abc.com/somewhere。否則可能會導致簽名和服務端對應不上。 27 28 步驟1. sort()含義為對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序) 29 30 步驟2. assemble()含義為根據步驟1中獲的參數字段的順序,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串 31 32 步驟2. sha1()的含義為對在步驟2拼接好的字符串進行sha1加密。
其實仔細看來你就會發現,他們的唯一不同的地方就在於:移動端有url的編碼,另外我可以告訴你,有沒有編碼的這一部分取決於你的url中是否存在中文字符,那么問題來了,是不是說移動和PC端的應用開發可以用同一套的簽名呢?
答案是肯定的,而且是必須的!
為什么呢?
因為,在你獲取accessToken的時候,你會發現他需要傳入的參數只有corpId與CorpSecret,而且這兩個入參是死值,也就是說,一個企業到的accessToken只有一個,而一個accessToken對應一個js_tiket,而且他們是存在時效和調取限制的yo!
1 建立連接 2 3 更新時間:2016/07/15 訪問次數:31492 4 主動調用 5 主動調用的頻率限制 6 獲取AccessToken 7 獲取微應用后台管理免登SsoToken 8 你可以使用以下兩種方式,將釘釘微應用連接到你的企業應用: 9 10 企業應用服務器調用釘釘開放平台提供的接口,以釘釘微應用的身份給企業用戶的釘釘賬號推送消息,以下稱 主動調用模式。 11 12 釘釘用戶在使用企業提供的微應用H5頁面時,該頁面可以調用釘釘提供的JS接口,使用釘釘開放的終端能力和業務能力,以下稱 JSAPI模式。 13 14 釘釘服務器把用戶發送的消息或用戶觸發的事件推送給企業應用,由企業應用處理,以下稱 回調模式。 15 16 主動調用 17 18 當企業應用服務器調用釘釘開放平台接口時,需使用https協議、Json數據格式、UTF8編碼,訪問域名為 https://oapi.dingtalk.com。 19 在每次主動調用釘釘開放平台接口時需要帶上AccessToken參數。AccessToken參數由CorpID和CorpSecret換取。對於ISV來說,獲取企業授權的access_token 20 21 CorpID是企業在釘釘中的標識,每個企業擁有一個唯一的CorpID; 22 23 CorpSecret是企業每個應用的憑證密鑰。 24 25 CorpID及CorpSecret可以在釘釘為企業提供的管理后台中找到,由釘釘自動分配。 26 27 POST請求請在HTTP Header中設置 Content-Type:application/json,否則接口調用失敗 28 主動調用的頻率限制 29 30 當你獲取到AccessToken時,你的微應用后台就可以成功調用釘釘后台所提供的各種接口或訪問相應企業的資源或給成員發消息。 31 32 為了防止微應用的程序錯誤而引發釘釘服務器負載異常,默認情況下,每個服務端調用接口都有一定的頻率限制,當超過此限制時,調用對應接口會收到相應錯誤碼。 33 34 以下是當前默認的頻率限制,釘釘后台可能會根據運營情況調整此閾值: 35 36 每個企業調用單個接口的頻率不可超過1500次/分 37 38 每個ISV(應用提供商)調用單個接口的頻率不可超過2000次/分 39 40 每個ISV(應用提供商)調用單個企業的單個接口頻率不可超過1500次/分 41 42 每個套件調用單個企業的單個接口頻率不可超過1000次/分 43 44 獲取AccessToken 45 46 AccessToken是企業訪問釘釘開放平台接口的全局唯一票據,調用接口時需攜帶AccessToken。 47 48 AccessToken需要用CorpID和CorpSecret來換取,不同的CorpSecret會返回不同的AccessToken。正常情況下AccessToken有效期為7200秒,有效期內重復獲取返回相同結果,並自動續期。
所以一般都會存在緩存策略,但是緩存策略的話會存在一個問題,那就是tiket的時效性問題!
即,一般公司存在多個項目時,大多會開發多個獨立的數據庫項目與之對應。往往會在其每個數據庫中獨自調用一種配置方法,但是這也是問題所在!所以我推薦大家采用多個項目調用一種配置的方法。這樣就不會存在tiket時效從而簽名驗證失敗的問題了!