基于SpringBoot实现图片防盗链的两种方式

 更新时间:2025年02月06日 09:49:23   作者:救救孩子把  
出于安全和性能的考虑,我们希望服务器返回的图片资源仅在指定网站内展示,防止爬虫或其它站点直接引用图片地址进行下载或展示,进而消耗服务器资源,所以本文给大家介绍了基于SpringBoot实现图片防盗链的两种方式,需要的朋友可以参考下

1. 实现目的

出于安全和性能的考虑,我们希望服务器返回的图片资源仅在指定网站内展示,防止爬虫或其它站点直接引用图片地址进行下载或展示,进而消耗服务器资源。简单来说,即在请求图片时通过检查 HTTP 请求头中的 Referer 来判断请求来源是否合法。

2. 简易实现方案

2.1 拦截器基本实现

在第一种方案中,代码写死了允许访问的域名(例如 “baidudu.com”),主要步骤如下:

  • 判断 URL 后缀
    当请求 URL 以 “.jpg”、“.png”、“.jpeg” 等图片格式结尾时,再进行后续判断。

  • 检查 Referer
    从请求头中取出 Referer,若不为空且包含预设允许的域名,则放行;否则返回 403 错误码,从而拒绝访问。

例如:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    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("baidudu.com")) {
            return true;
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return false;
        }
    }
    return true;
}

注册拦截器时,采用 Spring Boot 的 WebMvcConfigurer 接口将该拦截器应用于所有请求路径。

3. 灵活配置实现方案

为了使防盗链的配置更加灵活,可以将配置项(例如是否开启防盗链、是否允许浏览器直接访问、白名单域名等)写在 application.yml 中,并利用配置类映射到 Java 对象中。

3.1 配置文件示例

在 application.yml 中定义如下配置:

img-protect:
  enabled: true
  allowBrowser: false
  allowReferer: baidudu.com

3.2 映射配置类

利用 @ConfigurationProperties 将配置项映射到 Java 类中,方便后续使用:

@Component
@ConfigurationProperties("img-protect")
public class ImgProtectConfig {
    private boolean enabled;
    private boolean allowBrowser;
    private String allowReferer;
    // getter/setter 略
}

3.3 拦截器实现细节

在新版拦截器中,通过注入上述配置类,实现如下逻辑:

  • 若防盗链功能未开启,则直接放行。
  • 对图片资源请求(通过 URL 后缀判断):
    • 如果 Referer 为空且允许浏览器直接访问(allowBrowser 为 true),则放行;
    • 如果 Referer 不为空,则调用辅助方法判断 Referer 是否包含配置中允许的域名(允许多个域名,逗号分隔);
    • 否则返回 403。

例如:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (!imgProtectConfig.getEnabled()){
        return true;
    }
    String requestUrl = request.getRequestURL().toString();
    if (requestUrl.endsWith(".jpg") || requestUrl.endsWith(".png") || requestUrl.endsWith(".jpeg")) {
        String referer = request.getHeader("Referer");
        if (referer == null && imgProtectConfig.getAllowBrowser()){
            return true;
        } else if (referer != null && isAllowedDomain(referer)) {
            return true;
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return false;
        }
    }
    return true;
}

其中 isAllowedDomain 方法遍历配置中允许的多个域名进行比对。

4. 注意事项及局限性

虽然这种通过检查 Referer 实现的防盗链功能在一般场景下能有效防止资源被盗用,但仍存在一些不足之处:

  • Referer 伪造:恶意客户端可以伪造 Referer 头信息,绕过检测。
  • 漏报问题:攻击者可能利用 data URI 或 Base64 编码等方式绕过检查。
  • 误报问题:部分合法用户(例如使用隐私浏览器或代理服务器时)可能因 Referer 不匹配而被误拦截。
  • 反向代理问题:攻击者可能利用反向代理手法,通过 URL 路径中加入白名单域名绕过 contains 判断。

因此,该方法只是基本防护手段,并不能保证绝对安全,实际应用中可结合更严格的安全措施(如 Token 验证、Nginx 防盗链等)来共同提升防护效果。

5. 总结

本文展示了两种基于 Spring Boot 实现图片防盗链的方式:

  1. 简单写死配置的方式,直接在拦截器中判断 Referer;
  2. 基于配置文件灵活配置的方式,通过 application.yml 配置防盗链参数,并在拦截器中使用。

虽然这种方法能对一般情况下的盗链行为起到一定防护作用,但考虑到 Referer 可伪造等问题,实际项目中还需根据具体场景综合考虑更全面的安全策略。

到此这篇关于基于SpringBoot实现图片防盗链的两种方式的文章就介绍到这了,更多相关SpringBoot图片防盗链内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解Java运行时数据区_动力节点Java学院整理

    深入理解Java运行时数据区_动力节点Java学院整理

    这篇文章主要介绍了Java运行时数据区的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-06-06
  • java中json-diff简单使用及对象是否一致详解

    java中json-diff简单使用及对象是否一致详解

    这篇文章主要为大家介绍了java中json-diff简单使用及对象是否一致对比详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • java并发编程synchronized底层实现原理

    java并发编程synchronized底层实现原理

    这篇文章主要介绍了java并发编程synchronized底层实现原理
    2022-02-02
  • SpringBoot新手入门的快速教程

    SpringBoot新手入门的快速教程

    这篇文章主要给大家介绍了关于SpringBoot新手入门的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用SpringBoot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12
  • JavaWeb 实现多个文件压缩下载功能

    JavaWeb 实现多个文件压缩下载功能

    文件下载时,我们可能需要一次下载多个文件,批量下载文件时,需要将多个文件打包为zip,然后再下载。本文给大家分享实现思路及具体实现代码,对javaweb实现文件压缩下载功能感兴趣的朋友一起学习吧
    2017-07-07
  • Java如何基于ProcessBuilder类调用外部程序

    Java如何基于ProcessBuilder类调用外部程序

    这篇文章主要介绍了Java如何基于ProcessBuilder类调用外部程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java 11 正式发布,这 8 个逆天新特性教你写出更牛的代码

    Java 11 正式发布,这 8 个逆天新特性教你写出更牛的代码

    美国当地时间9月25日,Oracle 官方宣布 Java 11 (18.9 LTS) 正式发布,可在生产环境中使用!这是自 Java 8 后的首个长期支持版本
    2018-09-09
  • JavaMail入门教程之解析邮件(5)

    JavaMail入门教程之解析邮件(5)

    这篇文章主要为大家详细介绍了JavaMail入门教程之解析邮件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Java工具jsch.jar实现上传下载

    Java工具jsch.jar实现上传下载

    这篇文章主要为大家详细介绍了Java操作ftp的一款工具,利用jsch.jar针对sftp的上传下载工具类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • SpringBoot事件机制相关知识点汇总

    SpringBoot事件机制相关知识点汇总

    这篇文章主要介绍了SpringBoot事件机制相关知识点汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论