1. 程式人生 > >防盜鏈概念詳解以及自己使用tomcat實現一個防盜鏈

防盜鏈概念詳解以及自己使用tomcat實現一個防盜鏈

最近在使用阿里雲OSS雲端儲存的時候接觸到了防盜鏈這麼一個概念。

我們先從什麼是防盜鏈開始講起。

假設我們有這樣一個場景。
張三同學有一個網站。網站的圖片資源是存放在阿里雲的OSS的雲端儲存上的。
我們知道如果我們將圖片或者視訊等檔案上傳到oss,我們可以得到一個url。我們可以通過得到的url來訪問該圖片或者是視訊資源。
那麼現在問題來了。有一個同學是李四。李四同學也架設了一個網站。並且,李四同學正愁沒有圖片和視訊資源供訪問者訪問的時候,發現了張三同學在阿里雲oss上儲存的資源。於是乎,就將分析得到的url統統用
<img>標籤囊括到自己的網站下。訪客在訪問李四同學的網站時,看到的是李四同學的網站品牌。然而資料內容的實際提供者是張三同學。這時候張三同學就很冤啊,花了OSS儲存的流量的錢,卻沒有相應的使用者量。

所以現在有一個措施叫防盜鏈。
我們可以開啟阿里OSS儲存的控制檯去看看。
這裡寫圖片描述

筆者這裡設定了只有http://localhost:63342地址開頭的才能請求對應的圖片或者視訊資源。
這樣就避免了李四同學去蹭張三同學的流量了。

好奇的同學可能會問了。這是什麼原理?
原理其實是比較簡單的。
他是根據Http請求頭的Referer欄位的值來決定的。

筆者某一次的請求的http請求頭的名值對是這樣的。

Accept:image/webp,image/,/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
Connection:keep-alive
Host:banzhuannanzihan.oss-cn-shanghai.aliyuncs.com
Referer:

http://localhost:63342/aliyunossdemo/src/main/webapp/hello.html?_ijt=gcjgbr1iggi22d0kljvgnrbhqs
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

有的時候Referer欄位可能為空。

那麼既然如此我們可不可以自己在Tomcat上實現一個呢?
當然是可以的,而且實現起來很簡單。我們可以將邏輯寫到Tomcat的過濾器中。程式碼是這樣的

package
org.huluo.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(urlPatterns = "/*") public class RefererFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { System.out.println("過濾器初始化"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { System.out.println(((HttpServletRequest) request).getHeader("Referer")); //如果請求的來源是 http://localhost:63342開頭的,則讓其從tomcat上載入圖片資源 if (((HttpServletRequest) request).getHeader("Referer") != null && ((HttpServletRequest) request).getHeader("Referer").startsWith("http://localhost:63342")) { chain.doFilter(request, response); } else {//如果不是則讓其無法載入圖片 System.out.println("不讓過得到圖片"); if (response instanceof HttpServletResponse) { ((HttpServletResponse) response).setStatus(403,"不讓載入圖片"); } } } } public void destroy() { System.out.println("過濾器銷燬"); } }