前言
隨着互聯網的高速發展,無論是移動 APP 還是 WEB 站點,訪問的安全問題始終困擾着內容提供商。CDN ( Content Delivery Network,內容分發網絡 ) 服務作為當今互聯網世界的快遞專家扮演着更重要的角色,也承擔了更多的使命,在使用 CDN 服務的過程中,內容提供商提出了如下要求:
-
內容資源在經過 CDN 分發時,不被其他人惡意引用或者被非法下載
-
確保在使用 CDN 服務的過程中避免產生不必要的 CDN 帶寬浪費,從而節約成本
-
CDN 服務提供商提供的防盜鏈措施不容易被破解和繞過
基於以上要求,又拍雲作為雲 CDN 廠商的代表,認為傳統的 IP 禁用、referer 防盜鏈、User-Agent 防盜鏈、地區訪問控制等防盜鏈措施已經無法完全滿足用戶要求,今天我們專門來介紹一下更加高級的 token 防盜鏈。文章的末尾,為了實現更加靈活的 token 防盜鏈配置,我們引入了又拍雲自定義 rewrite 功能。
如何實現
Token 防盜鏈是通過對時間有關的字符串進行簽名,將時間、簽名信息通過一定的方式傳遞給 CDN 節點服務器作為判定依據,CDN 邊緣節點依據約定的算法判斷來訪的 URL 是否有訪問權限。如果通過,執行下一步;如果不通過,響應 HTTP 403 狀態碼或者通過 302 跳轉到其他 URL。
1、簽名參數
etime: URL 過期的時間,必須是 UNIX TIME 格式,如:2017/3/9 9:19:0 -> 1489022340
secret: 和 CDN 平台約定的簽名密鑰,需要在 CDN 管理控制台配置,如下圖(服務-> 全網加速 -> 配置 -> 防盜鏈 -> Token 防盜鏈)所示:
URI:請求 URL 的路徑部分(不包含 ? 及后面的 Query String),如客戶端訪問的外鏈地址為 http://xxx.b0.upaiyun.com/path/to/a.jpg?version=1.0,那么 URI 部分則為:/path/to/a.jpg
2、算法說明
sign = MD5( secret & etime & URI )
_upt = sign { 中間 8 位 }+etime
_upt = MD5( secret & etime & URI ){ 中間 8 位 } + etime
舉個例子:假設當前的 UNIX TIME 時間為:1370000000,某圖片資源(例如:http://test.example.com/dir/pic.jpg)10 分鍾有效,則:
etime = 1370000000 + 600 = 1370000600
uri = '/dir/pic.jpg'
sign = MD5( secret & etime & URI ) = xxxxxxxxxxxxabcdefghyyyyyyyyyyyy
_upt = MD5( secret & etime & URI ){ 中間 8 位 } + etime = abcdefgh1370000600
最后經過客戶端業務服務器生成的 URL 為:
http://test.example.com/dir/pic.jpg?_upt=abcdefgh137000060
3、業務流程
如下圖所示,整個 token 防盜鏈的實現需要如下幾個部分來配合:
1)客戶端:負責發送原始請求給客戶端業務服務器以及發送帶簽名的 URL 給 CDN 節點進行驗證
2)業務服務器:根據約定的算法生成帶 _upt 參數的 URL 返回給客戶端
3)CDN 節點:負責和客戶端進行時間、簽名校驗
4、實現方式
1)客戶端業務服務器生成驗證信息
驗證信息的生成由業務服務器負責,具體的加密過程需要確認如下事項:
-
確認過期時間的格式,默認采用 UNIX 時間戳格式
-
確認驗證信息中的密文,用戶計算驗證信息,需要和 CDN 平台約定
-
確認驗證信息時加入的參數,默認為 URL 的路徑部分
-
根據上文的算法說明計算驗證信息,其中請求 URL 中的驗證參數為 _upt
多語言生成 token 的例子參見 Github 地址:
https://github.com/upyun/token-examples
2)又拍雲 CDN 節點驗證過程
-
根據約定解析取出過期時間,和當前 CDN 節點服務器時間進行比較,確認請求是否過期
-
根據上文約定好的算法計算方式,計算出 MD5 加密串后,和 URL 中的加密串進行比較,驗證加密串是否一致
-
如果以上兩個步驟都驗證通過,請求才會被認為是合法的,這時 CDN 會請求資源響應給客戶端,否則會被認為是非法請求,直接響應 HTTP status code 403
擴展閱讀
為了兼容其他廠商的 token 防盜鏈規則或者需要實現更加復雜的 token 防盜鏈,結合又拍雲自定義 rewrite 功能就可以快速實現,無需定制化,一條簡單的規則就可以滿足要求。
例如,如下 URL 為某 CDN 廠商的和用戶約定的訪問 URL 規則:
http://example.com/test.png?key=1b7915a3059bf510500316ed262b58da&time=575f3027
此時,只需要結合又拍雲自定義 rewrite 配置一條規則即可滿足要求,規則如下所示:
$WHEN($NOT($ALL($GT($INT($_GET_, 16), &_Time),$EQ($_GET_key, $MD5(test $_URI $_HOST $_GET_TIME)))))$EXIT(403)
規則解釋:上面的規則主要是比較 time 和 key 的值,只有當過期時間大於本地時間,同時 key 的值和 CDN節點計算的 MD5 值一致,則驗證通過;當不滿足的時候,會返回 403。
總之,結合又拍雲自定義 rewrite 功能,可以快速實現超強版的 token 防盜鏈。
轉載自:Token 防盜鏈詳解