一文搞定防盜鏈設計

蓝胖子的编程梦發表於2024-04-02

大家好,我是藍胖子,在涉及到圖片或者影片連結時,通常都會提到防盜鏈,這一節我將會從防盜鏈的含義到落地,向大家展示如何設計資源的防盜鏈。

防盜鏈的含義與作用

防盜鏈,顧名思義,是為了防止資源被他人竊取而設計的。

通常我們將圖片或影片連結儲存到obs物件儲存上,前端透過服務端返回的圖片或影片連結訪問obs上對應的資源,那如果這個連結被第三方網站獲取到,便能在其網站上直接訪問我們的影片或者圖片資源。

防盜鏈的出現就是為了杜絕第三方網站能直接訪問我們的影片或圖片資源。讓返回的資源連結只能被我們指定的網站進行訪問

防盜鏈方案設計

接著,我以華為雲的obs系統 為例, 講幾個關於防盜鏈的設計方案,供大家參考,

refer指定黑白名單

瀏覽器在載入靜態資源時,會在請求頭中加上Refer欄位,其值為瀏覽器當前的網址,目的是為了告訴伺服器,使用者在訪問資源之前的位置。

如果第三方網站獲盜取到了我們的影片資源,那麼在其訪問時,Refer就是第三方網站的網址,我們可以在obs上配置reder黑白名單,指定資源讓某些網站不允許訪問或者對某些網站允許訪問。

Pasted image 20240401163901.png

更加靈活的鑑權方式-遠端鑑權

除此以外,還有種更加靈活的鑑權方式,透過自定義的程式碼來判斷該訪問連結是否允許被訪問。在使用obs系統時,為了減少頻寬成本,我們將會在obs前面,部署cdn節點,讓使用者訪問的資源能夠被快取到離他比較近的cdn節點上。

通常cdn節點上可以配置對應的訪問,例如華為雲可以配置遠端鑑權的地址,指向自己的伺服器鑑權介面,在介面中定義對資源的訪問許可權,像cloudflare則是可以建立worker,在worker中定義連結的訪問許可權。

Pasted image 20240401164545.png

鑑權邏輯應該如何寫,這裡我提供一個比較通用的邏輯,給大家參考下。

在服務端返回給客戶端資源在obs上的訪問連結時,可以加上該連結的建立時間,在鑑權邏輯裡申明一個連結的有效期,根據連結的產生時間和有效期 允許該連結在有效期內允許訪問,比如返回給客戶端的連結是

https://xxx?ctime=1711962048

ctime 則是連結的建立時間,但是僅僅這樣是不夠的,第三方網站可以獲取到連結後修改ctime欄位來修改連結的建立時間,所以我們還需要一個訊息認證的機制,保證連結是伺服器返回的且沒有經過篡改,這裡可以用訊息認證演算法實現。

拿訊息認證演算法hmac舉例,伺服器端定義一個只有自己知道的金鑰,用該金鑰對資源地址進行md5的摘要計算,如下是golang中的hamc的使用邏輯,

key := "hamcsecrete"
    data := "https://xxx?ctime=1711962048"
    hmac := hmac.New(md5.New, []byte(key))
    hmac.Write([]byte(data))
    fmt.Println(hex.EncodeToString(hmac.Sum([]byte(""))))

得到的訊息認證碼,加入到資源連結的引數中,如下,

https://xxx?ctime=1711962048&token=679f5d6f7d344dba1e33938ae1d41ab4

這樣,鑑權伺服器在得到資源連結時,就會將資源地址透過同樣的訊息認證演算法和金鑰計算token值,如果計算出的token值和資源連結中的token值一致,則繼續檢視連結是否在有效期範圍內,在則允許訪問,否則不允許訪問。因為訊息認證的金鑰只有伺服器知道,即使第三方網站獲取到了連結,也無法得出正確的token值。

最後,在使用此邏輯的時候,要注意cdn伺服器回源的條件,通常cdn是根據url路徑檢視是否需要回源,如果url地址不同,則會去訪問源站伺服器,我們當然不希望因為連結ctime的不同就再次去請求源站伺服器,所以,在cdn節點處,需要配置,判斷回源時需要忽略ctime和token的引數。

相關文章