最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實現(xiàn)文章防盜鏈的代碼設計

 更新時間:2024年05月13日 09:48:57   作者:shigen01  
這篇文章主要介紹了SpringBoot實現(xiàn)文章防盜鏈的代碼設計,文中通過代碼示例講解的非常詳細,對大家實現(xiàn)文章防盜鏈功能有一定的幫助,需要的朋友可以參考下

來今天的正題:springboot實現(xiàn)圖片防盜鏈。可能看起來場景比較抽象,這里shigen給出之前的一個例子:對象存儲服務的流量被盜刷了,當時官方給的解決方案包括我后來采用的方式就是referer的限制。

后來我的對象存儲服務的流量就正常了。那今天我也是好奇這個用springboot怎么實現(xiàn)。在接下來的內(nèi)容中,我將會著重分享我的設計。

首先了解一下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)文章防盜鏈的代碼設計的詳細內(nèi)容,更多關于SpringBoot文章防盜鏈的資料請關注腳本之家其它相關文章!

相關文章

最新評論

海城市| 资中县| 韩城市| 区。| 丘北县| 长岭县| 时尚| 碌曲县| 介休市| 新巴尔虎右旗| 荥阳市| 建阳市| 灵台县| 佛山市| 通渭县| 孟津县| 综艺| 和平区| 新余市| 栾川县| 德安县| 鹤山市| 阳山县| 洛浦县| 昌邑市| 岑溪市| 肥东县| 保德县| 乌海市| 娄烦县| 乌兰察布市| 石河子市| 修水县| 庆阳市| 临桂县| 林口县| 阿鲁科尔沁旗| 东山县| 连平县| 玛沁县| 长治县|