java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot图片防盗链

SpringBoot实现图片防盗链功能

作者:前阿里高级码农

出于安全考虑,我们需要后端返回的图片只允许在某个网站内展示,不想被爬虫拿到图片地址后被下载,或者,不想浏览器直接访问图片链接,所以本文将给大家介绍SpringBoot实现图片防盗链功能,需要的朋友可以参考下

前言

出于安全考虑,我们需要后端返回的图片只允许在某个网站内展示,不想被爬虫拿到图片地址后被下载。或者,不想浏览器直接访问图片链接。

出于性能考虑,不想要别人的网站,拿着我们的图片链接去展示,白白消耗自己的服务器资源。

故而可在springboot中,使用简单的图片防盗链规则。拦截掉一些处理。

1、代码实现

本篇实战代码是简易版,代码写死配置

1-1、创建拦截器类

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse;
    public class ImageProtectionInterceptor implements HandlerInterceptor {    
       
        private static final 
       
        String ALLOWED_DOMAIN = "baidudu.com"; // 允许的域名    @Override    
        
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
        
        throws Exception {        // 获取请求的 URL        
      
        String requestUrl = request.getRequestURL().toString();        // 判断请求是否以图片后缀结尾        
      
        if (requestUrl.endsWith(".jpg") || requestUrl.endsWith(".png") || requestUrl.endsWith(".jpeg")) {            // 获取请求的来源域名            
      
        String referer = request.getHeader("Referer");            // 检查来源域名是否符合预期            
      
        if (referer != null && referer.contains(ALLOWED_DOMAIN)) {                
         
            return true; // 符合防盗链要求,放行请求            
           
            } else {                
         
            response.sendError(HttpServletResponse.SC_FORBIDDEN); // 返回 403 Forbidden                
         
            return false; // 拦截请求         
         
            }       
         
   }        
         
            return true; // 对非图片资源请求放行  
            }
        
    }

2、代码实现(灵活配置)

2-1、在 application.yml 中配置信息

# 图片防盗链配置img-protect: 
# 图片防盗链保护开关  
enabled: true  
# 是否允许浏览器直接访问  
allowBrowser: false  
# 图片防盗链白名单,多个用逗号分隔【不填则所有网站都拦截】 
allowReferer: baidudu.com

2-2、创建配置文件映射类

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component@ConfigurationProperties("img-protect")

        public class ImgProtectConfig {    
          private boolean enabled;    
   
          private boolean allowBrowser;    
  
          private String allowReferer;    
  
          public boolean getEnabled() {        
           
               return enabled;    
        
    }    
    
          public void setEnabled(boolean enabled) {        
              
              this.enabled = enabled;   
              
              
          }    
              public boolean getAllowBrowser() {        
                  
                  return allowBrowser;   
                  
                  
              }   
              
         public void setAllowBrowser(boolean allowBrowser) {       
                 
            this.allowBrowser = allowBrowser;    
             
             
         }    
         
         public String getAllowReferer() {       
             
             return allowReferer;    
             
         }    
         
         public void setAllowReferer(String allowReferer) {        
             
             this.allowReferer = allowReferer;   
             
             
         }
            
        }

2-3、创建拦截器类

import 上方2-2创建的类路径.ImgProtectConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Componentpublic 

class ImageProtectionInterceptor implements HandlerInterceptor {    
   
    @Autowired    
    
    private ImgProtectConfig imgProtectConfig;    
    
    @Override    
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  // 判断是否开启图片防盗链功能        
   
    if (!imgProtectConfig.getEnabled()){            
        
        return true;       
        
    }                // 获取请求的 URL        
    
    String requestUrl = request.getRequestURL().toString();        // 判断请求是否以图片后缀结尾        
    
    if (requestUrl.endsWith(".jpg") || requestUrl.endsWith(".png") || requestUrl.endsWith(".jpeg")) {            // 获取请求的来源域名            
    
    String referer = request.getHeader("Referer");            // 检查来源域名是否符合预期,referer 为 null 则说明是浏览器直接访问。            
    
    if (referer == null && imgProtectConfig.getAllowBrowser()){                
        
        return true; // 符合防盗链要求,放行请求            
        
        
    }else if (referer != null && isAllowedDomain(referer)) {                
        
    return true; // 符合防盗链要求,放行请求            
    
        
    } else {                
        
    response.sendError(HttpServletResponse.SC_FORBIDDEN); // 返回 403 Forbidden                
    
    return false; // 拦截请求           
        
         }       
    
    }        
    
    return true; // 对非图片资源请求放行    
    
        
    }    // 检查是否来自允许的域名    
    
    private boolean isAllowedDomain(String referer) {        
        
        // 获取允许的域名        
        String allowedReferers = imgProtectConfig.getAllowReferer();        
        
        // 如果允许的域名不为空        
        if (allowedReferers.trim() != null && !"".equals(allowedReferers.trim())) {            
            
            // 将允许的域名分割成字符串数组            
        Set<String> allowedDomains = new HashSet<>(Arrays.asList(allowedReferers.split(",")));            
        
        // 遍历允许的域名            
        for (String allowedDomain : allowedDomains) {                
        
        // 如果请求的域名包含允许的域名,则返回true                
        if (referer.contains(allowedDomain.trim())) {                    
            
            return true;               
            
            
        }           
        
            
        }      
        
            
        }        
        
        // 否则返回
        false        
        
        return false;    
        
    }
    
}

2-4、注册拦截器

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration

    public class WebConfig implements WebMvcConfigurer {  
        
        // 不能再使用 new 方式创建对象 !!!  
        @Autowired    
         private ImageProtectionInterceptor imageProtectionInterceptor;   
        
        @Override    
        public void addInterceptors(InterceptorRegistry registry) {        
        
        // 注册拦截器,拦截所有请求        
        registry.addInterceptor(imageProtectionInterceptor)                
        .addPathPatterns("/**"); 
        // 拦截所有请求    
        }
        
    }

结束语

以上防盗链拦截器基本实现可以对付一般情况下的图片盗链,但并不能保证绝对安全。

可能出现以下等情况:

以上就是SpringBoot实现图片防盗链功能的详细内容,更多关于SpringBoot图片防盗链的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文