防盜鏈概念詳解以及自己使用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("過濾器銷燬");
    }
}

發佈了241 篇原創文章 · 獲贊 71 · 訪問量 73萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章