基于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 实现图片防盗链的方式:
- 简单写死配置的方式,直接在拦截器中判断 Referer;
- 基于配置文件灵活配置的方式,通过
application.yml
配置防盗链参数,并在拦截器中使用。
虽然这种方法能对一般情况下的盗链行为起到一定防护作用,但考虑到 Referer 可伪造等问题,实际项目中还需根据具体场景综合考虑更全面的安全策略。
到此这篇关于基于SpringBoot实现图片防盗链的两种方式的文章就介绍到这了,更多相关SpringBoot图片防盗链内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!