图片防盗链(Image Hotlinking Prevention)是一种常见的安全措施,旨在防止其他网站未经许可直接引用你的图片资源。这不仅能保护你的服务器带宽,避免不必要的资源消耗,还可以保证你的网站内容的版权和完整性。
在这篇文章中,我们将详细分析前端和后端如何配合实现图片防盗链技术,特别是在 Spring Boot 环境下的解决方案。
1. 图片防盗链的原理分析
1.1 什么是图片防盗链?
盗链(Hotlinking)指的是其他网站通过直接引用你网站的资源(如图片、视频、样式表等),而不是下载这些资源到自己的服务器,从而消耗你网站的带宽和资源。这种做法不仅影响服务器性能,还可能导致版权问题和内容篡改的风险。
图片防盗链技术,就是通过一系列手段来防止其他网站直接引用你的图片。
1.2 防盗链的基本原理
防盗链的核心思想是通过验证请求的来源(如 HTTP 请求头中的 Referer
字段)来确保请求来自合法的来源网站。如果请求来自非法网站(即请求头中的 Referer
不是预期中的域名),则拒绝该请求,返回错误或占位图。
常见的防盗链方法包括:
- Referer 校验:验证请求的
Referer
字段,只有合法来源才能访问资源。 - Token 校验:生成有效的 token,并将其附加在 URL 中进行校验。
- 签名校验:对 URL 进行加密签名,验证请求是否合法。
2. 前端解决方案:Referer 校验
虽然防盗链的核心功能通常由后端实现,前端也可以通过某些方式配合防盗链。
2.1 使用 Referer
校验
当一个图片被加载时,浏览器会自动发送一个 HTTP 请求,其中包括 Referer
字段,该字段指示了图片请求的来源页面。通过后端检查该字段,我们可以判断请求是否来自允许的域名。
例如,在前端加载图片时,如果我们希望限制图片的引用来源为自己的站点,后端就可以检查 Referer
是否为本站域名。
<!-- 前端页面引用图片 -->
<img src="https://yourdomain.com/images/pic.jpg" alt="image">
当用户访问该页面时,浏览器会发送如下请求:
GET /images/pic.jpg HTTP/1.1
Host: yourdomain.com
Referer: https://alloweddomain.com
在这种情况下,服务器可以根据 Referer
字段的值进行判断,若请求来源不合法,则拒绝返回图片。
3. 后端解决方案:Spring Boot 实现图片防盗链
在 Spring Boot 中,我们可以通过过滤器或拦截器来检查 HTTP 请求中的 Referer
字段,并进行防盗链操作。下面是一个基于 Spring Boot 的实现方案。
3.1 使用过滤器拦截图片请求
Spring Boot 提供了强大的过滤器机制,允许我们在请求到达控制器之前对请求进行处理。我们可以使用一个过滤器来拦截图片请求,检查 Referer
字段是否来自合法的来源。
3.1.1 定义防盗链过滤器
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(urlPatterns = "/images/*") // 只拦截图片资源请求
public class ImageAntiHotlinkingFilter implements Filter {
private static final String ALLOWED_REFERER = "https://www.yourdomain.com"; // 允许的来源域名
private static final String DEFAULT_IMAGE_URL = "/images/default.jpg"; // 防盗链时显示的默认图片
@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;
String referer = httpRequest.getHeader("Referer");
// 判断请求的 Referer 是否合法
if (referer == null || !referer.startsWith(ALLOWED_REFERER)) {
// 非法来源,重定向到默认图片
httpResponse.sendRedirect(DEFAULT_IMAGE_URL);
return;
}
// 合法请求,继续处理
chain.doFilter(request, response);
}
@Override
public void destroy() {
// 销毁操作
}
}
3.1.2 注册过滤器
然后,在 Spring Boot 中通过 @Configuration
注解将该过滤器注册到 Spring 容器中。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<ImageAntiHotlinkingFilter> imageFilter() {
FilterRegistrationBean<ImageAntiHotlinkingFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ImageAntiHotlinkingFilter());
registrationBean.addUrlPatterns("/images/*"); // 只拦截图片路径
return registrationBean;
}
}
3.2 使用 Spring Security 防盗链(更细致控制)
如果你已经使用 Spring Security 进行访问控制,你可以将防盗链的逻辑与 Spring Security 配置结合起来,进行更精细的安全控制。
例如,你可以通过 HttpSecurity
配置来实现对特定资源的访问控制:
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/images/**").permitAll() // 图片路径允许匿名访问
.anyRequest().authenticated()
.and()
.addFilterBefore(new ImageAntiHotlinkingFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
这种方法可以结合 Spring Security 实现更细致的权限管理。
3.3 防盗链的其他高级实现
如果你希望防盗链更加安全,可以考虑:
- Token 防盗链:在图片 URL 中嵌入临时有效的 token,并在后端进行验证。
- 时间戳防盗链:通过 URL 中添加时间戳,只有在有效时间段内才允许访问。
- 签名防盗链:对 URL 进行签名,确保 URL 的合法性。
4. 总结
防盗链的实现方式有很多种,主要通过验证请求来源来防止外部网站恶意使用你的资源。在前端,我们可以通过配置图片的引用方式、使用 Referer
校验来限制资源访问。而在后端,Spring Boot 提供了过滤器和 Spring Security 的配置,使得我们可以方便地实现防盗链功能。
通过这篇文章,我们详细分析了如何实现图片防盗链技术,以及如何在 Spring Boot 环境下结合过滤器和 Spring Security 完成该功能的实现。
发表回复