您的位置: 首页> Java源码> 你的图片又被别人“白嫖”了?用这篇Java防盗链攻略说再见!

你的图片又被别人“白嫖”了?用这篇Java防盗链攻略说再见!

时间:2025-09-09 14:15:01 来源:互联网

01 引言

公司领导对数据安全非常看重,要求我们的系统中的图片链接,不能在其他地方打开,只能在系统中查看,要求我们整改系统。这玩意怎么整呀,图片资源服务器在我们公司本身就是可以对外公开访问图片的,怎么才能实现既要能访问又要不能访问呢?

防盗链是首先能想到的方案。我们今天一起来唠唠!

02 外部效果

我们先看看外部网站的效果,我们以百度图片为例:

通过查看源码,可以看到图片的具体地址:

ww2.sinaimg.cn/mw690/007ut…

但是直接访问时,却无法访问:

这就实现了图片的防盗功能。

03 防盗链的工作原理

防盗链的核心原理是检查HTTP请求头中的 Referer 字段。

04 最佳实践

最高效、最常用的方式是在Web服务器层面配置,例如 Nginx。这种方式性能损耗极小。此方案不是本节讨论的重点,我们从Java开发角度取实现。

了解防盗链的工作原理之后,我们只需要通过拦截器或者过滤器,拦截指定的请求,通过Header中的Referer属性,就可以实现。

我们通过过滤器来实现,因为很多时候图片属于静态资源,而过滤去默认拦截静态资源。

4.1 创建拦截器

public class ImageReferFilter implements Filter {

    public static final String REFERER = "Referer";
    public static final String ALLOW_DOMAIN = "127.0.0.1:8080";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        String url = httpServletRequest.getRequestURL().toString();
        // 过滤图片资源
        if (StringUtils.isNotEmpty(url) && StringUtils.endsWithAny(url.toLowerCase(), ".jpg", ".png", ".gif", ".jpeg")) {
            String header = httpServletRequest.getHeader(REFERER);
            // 来自本地,就放行
            if (StringUtils.isNotEmpty(header) && StringUtils.contains(header, ALLOW_DOMAIN)) {
                chain.doFilter(request, response);
                return;
            }

            // 拦截输出403
	 		httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
			httpResponse.getWriter().write("<h1>403 Forbidden</h1><p>You don't have permission to access the URL on this server.</p>");
            return;
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

输出结果可以根据自己的业务定制,如:

返回403禁止访问状态码

response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Hotlinking is not allowed.");

请求重定向到指定图片

// 假设我们在网站根目录的 /images/ 下放了一张提示图片 anti-hotlinking.jpg
String warningImagePath = "/images/anti-hotlinking.jpg";
response.sendRedirect(warningImagePath);

4.2 配置拦截器

@Bean
FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean filter = new FilterRegistrationBean();
    filter.setFilter(new ImageReferFilter());
    filter.addUrlPatterns("/*");
    return filter;
}

4.3 页面展示

我们在static下放了一张样例图,通过页面<img>标签引用图片。

4.4 启动效果展示

我们也实现了类似百度图片防盗的效果。

05 注意事项

防盗链拦截器只能解决一般情况的图片防盗,并不能保证绝对的安全。所以使用时应该注意:

上一篇:Java异常处理别再瞎搞了!阿里大神总结的 9 种最佳实践,让你的代码更健壮! 下一篇:synchronized 的可重入性:避免死锁的隐藏武器

相关文章

相关应用

最近更新