防盗链(Hotlink Protection)是一种防止其他网站直接链接到你网站的资源(如图片、视频等),从而节省带宽和保护内容的有效手段。在Spring Boot应用程序中实现防盗链功能,可以通过多种方式来达成,例如使用过滤器(Filter)、拦截器(Interceptor),或者通过配置Nginx等反向代理服务器。
以下是几种实现防盗链的方法:
1. 使用过滤器(Filter)
你可以创建一个自定义过滤器,在请求到达实际资源之前检查HTTP头中的`Referer`字段。如果`Referer`不在允许的域名列表中,则返回403 Forbidden响应或重定向到其他页面。
```java
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HotlinkProtectionFilter implements Filter {
private final String[] allowedDomains = {"yourdomain.com"};
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String referer = httpRequest.getHeader("Referer");
// Allow if there's no Referer (like direct access or bookmarks)
if (referer == null || Arrays.stream(allowedDomains).anyMatch(referer::contains)) {
chain.doFilter(request, response);
} else {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Hotlinking not allowed");
}
}
@Override
public void destroy() {}
}
```
然后你需要将这个过滤器注册到Spring的上下文中:
```java
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<HotlinkProtectionFilter> loggingFilter(){
FilterRegistrationBean<HotlinkProtectionFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new HotlinkProtectionFilter());
registrationBean.addUrlPatterns("/resources/*"); // 替换为你的资源路径
return registrationBean;
}
}
```
2. 使用拦截器(Interceptor)
如果你更倾向于MVC模式,可以创建一个拦截器来执行相同的逻辑:
```java
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class HotlinkProtectionInterceptor implements HandlerInterceptor {
private final String[] allowedDomains = {"yourdomain.com"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String referer = request.getHeader("Referer");
if (referer == null || Arrays.stream(allowedDomains).anyMatch(referer::contains)) {
return true;
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Hotlinking not allowed");
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
```
接着,需要注册该拦截器:
```java
import org.springframework.beans.factory.annotation.Autowired;
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 {
@Autowired
private HotlinkProtectionInterceptor hotlinkProtectionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(hotlinkProtectionInterceptor).addPathPatterns("/resources/**");
}
}
```
3. 配置Nginx
如果你的应用程序是通过Nginx或其他反向代理服务器访问的,那么可以在Nginx配置文件中添加防盗链规则,这种方法通常更为高效:
```nginx
location /resources/ {
valid_referers none blocked yourdomain.com *.yourdomain.com;
if ($invalid_referer) {
return 403;
}
}
```
这三种方法都可以有效地防止其他网站直接链接到你的资源。选择哪种方法取决于你的具体需求和技术栈。