前端实现图片防盗链技术详解 – 原理分析与SpringBoot解决方案
图片防盗链技术是通过限制外部站点非法引用自己服务器上的资源,防止盗用带宽及流量,并保护版权和服务器资源。特别是当你的网站中包含大量图片资源时,如果不采取防盗链措施,其他网站可能会直接引用你的图片,而你却为这些图片的展示支付流量费用。为了防止盗链,常用的技术手段是基于HTTP请求头的Referer
字段。
本文将详细阐述图片防盗链的原理,并给出基于Spring Boot实现防盗链的解决方案。
一、防盗链原理分析
1. Referer头的原理
Referer
是 HTTP 请求头的一部分,表示当前请求页面的来源URL。网站服务器可以通过读取这个字段来判断请求是否来自自己的网站。如果请求的图片或资源来自非法来源(即非授权的站点),就可以拒绝提供资源。
- 合法请求:当图片被正确地从自己的站点加载时,
Referer
头会包含该站点的域名。 - 非法请求:如果其他站点直接引用图片,
Referer
头会显示那个站点的域名,这时候服务器就可以根据Referer
来判断请求是否是非法的。
2. 防盗链流程
- 用户在浏览器中请求图片资源。
- 浏览器自动附加
Referer
头,向图片服务器发起请求。 - 服务器检查
Referer
头,如果请求来自合法网站,则返回图片;如果请求来自非法网站,则返回错误信息(例如403 Forbidden)。
二、Spring Boot实现图片防盗链
1. 配置Spring Boot应用
在Spring Boot中,我们可以通过自定义过滤器来拦截HTTP请求,检查Referer
头,从而判断是否是合法的请求。
步骤:
- 创建一个过滤器(
Filter
),在过滤器中检查HTTP请求的Referer
头。 - 如果
Referer
合法,继续响应请求,否则返回403 Forbidden错误。
2. 自定义过滤器
首先,需要创建一个过滤器类来处理防盗链逻辑:
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "refererFilter", urlPatterns = "/images/*") // 监听图片资源请求
public class RefererFilter implements Filter {
// 白名单域名
private static final String[] ALLOWED_REFERERS = {
"https://www.yourwebsite.com",
"https://www.other-allowed-site.com"
};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作,可以不做任何处理
}
@Override
public void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 获取Referer头
String referer = httpRequest.getHeader("Referer");
if (referer == null || !isAllowedReferer(referer)) {
// 非法Referer,返回403
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpResponse.getWriter().write("Forbidden: You are not allowed to access this resource.");
return;
}
// 合法Referer,继续执行请求
chain.doFilter(request, response);
}
@Override
public void destroy() {
// 清理操作,可以不做任何处理
}
// 判断Referer是否在允许的白名单中
private boolean isAllowedReferer(String referer) {
for (String allowedReferer : ALLOWED_REFERERS) {
if (referer.startsWith(allowedReferer)) {
return true;
}
}
return false;
}
}
在上面的代码中:
urlPatterns = "/images/*"
:表示只对/images/
路径下的图片资源进行防盗链处理。ALLOWED_REFERERS
:存储合法站点的白名单,只有在这个白名单中的站点,才可以访问图片资源。doFilter
方法中判断请求的Referer
是否合法,如果合法,继续处理请求;如果非法,返回403错误。
3. 注册过滤器
在Spring Boot中,过滤器需要注册才能生效。你可以通过配置类将过滤器注册到应用中。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<RefererFilter> refererFilter() {
FilterRegistrationBean<RefererFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new RefererFilter());
registrationBean.addUrlPatterns("/images/*"); // 只拦截/images/*路径下的图片请求
return registrationBean;
}
}
4. 启动并测试
- 启动Spring Boot应用,确保过滤器已正确注册。
- 访问图片时,从合法网站请求资源,将会成功返回图片。
- 从非法网站请求资源,将返回
403 Forbidden
错误。
三、优化与扩展
1. 动态配置白名单
有时候白名单需要动态配置,而不是在代码中硬编码。你可以将白名单存储在数据库或配置文件中,在过滤器中读取。
private List<String> allowedReferers;
public RefererFilter() {
// 从配置文件或数据库加载白名单
this.allowedReferers = loadAllowedReferers();
}
private List<String> loadAllowedReferers() {
// 从配置文件、数据库或其他存储加载白名单
return Arrays.asList("https://www.yourwebsite.com", "https://www.other-allowed-site.com");
}
2. 设置缓存和其他防盗链策略
除了Referer
防盗链,还有其他防盗链策略,例如:
- 使用Token认证:在URL中附加唯一的Token,通过Token判断请求是否合法。
- 限制IP访问:通过
X-Forwarded-For
或RemoteAddr
限制访问的IP范围。
3. 提高性能
每次请求都需要检查Referer
头可能会带来性能问题,尤其是对于高流量的站点。你可以通过以下方式提高性能:
- 使用缓存存储合法
Referer
。 - 使用CDN加速图片的请求,同时支持防盗链设置。
四、总结
本文介绍了图片防盗链的基本原理及其实现方式,通过Spring Boot应用自定义过滤器来实现基于Referer
头的防盗链机制,防止其他站点非法引用你网站的图片资源。通过此方式,你可以有效保护网站资源、节约带宽,并保障版权。同时,还介绍了如何扩展和优化防盗链机制,例如动态配置白名单和设置其他防盗链策略。
发表回复