SpringBoot實現(xiàn)文章防盜鏈的代碼設計
來今天的正題:springboot實現(xiàn)圖片防盜鏈??赡芸雌饋韴鼍氨容^抽象,這里shigen給出之前的一個例子:對象存儲服務的流量被盜刷了,當時官方給的解決方案包括我后來采用的方式就是referer的限制。

后來我的對象存儲服務的流量就正常了。那今天我也是好奇這個用springboot怎么實現(xiàn)。在接下來的內容中,我將會著重分享我的設計。
首先了解一下Referer是什么吧。
什么是Referer
這里告別充滿廣告和垃圾網(wǎng)站的搜索引擎,直接GPT查詢:
Referer(來源)是HTTP頭部字段之一,用于指示客戶端是從哪個頁面跳轉或發(fā)起請求的。當客戶端(通常是瀏覽器)向服務器發(fā)送請求時,它會在HTTP頭部中包含 Referer 字段,告訴服務器請求的來源頁面的URL。這個字段可以幫助服務器了解請求的上下文和用戶行為,有助于進行數(shù)據(jù)分析、安全檢查等操作。
也就是說請求一個資源的時候,瀏覽器的請求頭信息中會帶上Referer字段標示出當下的請求的上一個請求是什么地方來的。
那基于這個原理,我們就可以設計出自己的防盜鏈。
java代碼的設計
基礎版
假設我們的springboot項目中可以直接通過http請求訪問到某個路徑下的資源。我們先這樣的嘗試吧。我們的配置肯定要實現(xiàn)WebMvcConfigurer這個接口,實現(xiàn)資源的映射。那我就直接展示我的代碼:
@Configuration
@EnableWebMvc
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
?
/**
* 靜態(tài)資源保存目錄
*/
public static final String FILE_RESOURCE_PATH = "file:" + System.getProperty("user.dir") + "/files/";
?
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
log.error("靜態(tài)資源保存目錄:{}", FILE_RESOURCE_PATH);
registry.addResourceHandler("/files/**")
.addResourceLocations(FILE_RESOURCE_PATH);
}
}
其實我們最終實現(xiàn)的文件路徑就是項目根路徑/files/文件夾的全部文件。
這樣我們就可以通過http請求訪問了。

但是,明顯的我們的資源不是很安全。因為任意來源、任何人都可以訪問到它。那我們限制來源的話,這個時候Referer就可以派上用場了。
升級版
升級版本,我們就需要統(tǒng)一攔截一下請求,看看請求頭中是否包含Referer信息,且是我們約定的Referer。這樣才能判定是正常的請求,進行流量的放行,否則的話就是要去攔截。
接下來先去設計一個攔截器:
@Slf4j
@Component
public class ResourceInterceptor extends HandlerInterceptorAdapter {
?
@Resource
private ReferConfig referConfig;
?
/**
* 匹配的文件種類
*/
private static final String FILE_REGEX = "\.(html|css|js|jpg|jpeg|png|gif|bmp|svg|pdf|doc|docx|xls|xlsx|ppt|pptx|mp4|mov)$";
private static final Pattern FILE_REGEX_PATTERN = Pattern.compile(FILE_REGEX, Pattern.CASE_INSENSITIVE);
?
?
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 獲取請求的 URL
String requestUrl = request.getRequestURL().toString();
log.info("requestUrl:{}", requestUrl);
// 檢查是否是靜態(tài)資源請求
if (referConfig.isEnabled() && isStaticResource(requestUrl)) {
// 檢查防盜鏈策略
if (!isValidReferer(request)) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return false;
}
}
return true;
}
?
/**
* 正則驗證請求的資源
*
* @param url 請求資源
* @return 是否匹配
*/
private boolean isStaticResource(String url) {
return FILE_REGEX_PATTERN.matcher(url).find();
}
?
/**
* 檢查 Referer 頭,判斷請求是否合法
*
* @param request 請求
* @return 是否是合法請求
*/
private boolean isValidReferer(HttpServletRequest request) {
String referer = request.getHeader("Referer");
return CollectionUtil.contains(referConfig.getAllowedOrigins(), referer);
}
}
具體的業(yè)務邏輯的驗證都在注釋里,這里需要注意:
- 關于
Referer的配置最好寫成動態(tài)的,便于后期的拓展 - 對于url的請求判斷最好使用正則表達式,因為url本身請求的就是靜態(tài)資源,但是后邊帶了其他的參數(shù)可能導致直接繞過
對于自定的配置類,shigen是這樣的設計:
@Configuration
@ConfigurationProperties(prefix = "refer")
@Data
public class ReferConfig {
/**
* 是否開啟防盜鏈攔截
*/
private boolean enabled;
/**
* 允許的Referer請求
*/
private List<String> allowedOrigins;
?
}
接下來就是配置到攔截器上。
@Configuration
@EnableWebMvc
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
?
@Resource
private UserArgumentResolver userArgumentResolver;
?
@Resource
private ResourceInterceptor resourceInterceptor;
?
/**
* 靜態(tài)資源保存目錄
*/
public static final String FILE_RESOURCE_PATH = "file:" + System.getProperty("user.dir") + "/files/";
?
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userArgumentResolver);
}
?
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(resourceInterceptor).addPathPatterns("/**");
}
?
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
log.error("靜態(tài)資源保存目錄:{}", FILE_RESOURCE_PATH);
registry.addResourceHandler("/files/**")
.addResourceLocations(FILE_RESOURCE_PATH);
}
}
待一切完成,我們這里再檢查一下配置文件就可以正常的啟動服務進行測試了。
refer:
enabled: true
allowed-origins:
- http://www.shigen.com
此時,我們再次在瀏覽器中直接訪問:

這時我們想要正常的訪問,就得借助于接口測試工具了。

以上就是SpringBoot實現(xiàn)文章防盜鏈的代碼設計的詳細內容,更多關于SpringBoot文章防盜鏈的資料請關注腳本之家其它相關文章!
相關文章
Spring Boot應用發(fā)布到Docker的實現(xiàn)
這篇文章主要介紹了Spring Boot應用發(fā)布到Docker的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
linux系統(tǒng)下java項目在后臺啟動的4種方式總結
Linux是集多種功能于一身的操作系統(tǒng),它可以讓用戶查看和管理當下正在運行的進程,包括Java程序,這篇文章主要給大家總結介紹了關于linux系統(tǒng)下java項目在后臺啟動的4種方式,需要的朋友可以參考下2023-10-10

