当前位置: 首页 > news >正文

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

01 引言

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

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

02 外部效果

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

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

https://ww2.sinaimg.cn/mw690/007ut4Uhly1hx4v37mpxcj30u017cgrv.jpg

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

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

03 防盗链的工作原理

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

  • Referer 字段表示这个请求是从哪个页面发起的。
  • 如果一张图片应该只在 www.mywebsite.com 上被访问,那么所有来自其他域名(如 www.othersite.com)的图片请求,其 Referer 字段都会是 http://www.othersite.com/somepage.html
  • 服务器通过校验这个 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";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}@Overridepublic 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;}// 拦截输出403httpResponse.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);}@Overridepublic 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 注意事项

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

  • Referer 的可伪造性Referer 头可以被某些客户端或代理恶意修改或移除,因此防盗链机制并非绝对安全,但足以应对绝大多数普通的盗链情况。
  • Referer 的处理:需要谨慎处理 Referer 为空的情况。浏览器直接输入地址、从HTTPS页面链接到HTTP资源(浏览器会屏蔽Referer)等都会导致其为空。根据你的安全要求,可以选择允许或拒绝。上述Java示例选择了允许
  • CDN的影响:如果你使用了CDN,需要确保CDN在回源请求时不会剥离或修改 Referer 头,或者将CDN的域名也加入白名单。
  • 对用户体验的影响:确保你自己的网站不会被自己的规则所阻挡。在设置好之后,一定要全面测试自己网站的功能。

文章转载自:

http://YvR414Id.kgLtb.cn
http://HTxgiJKK.kgLtb.cn
http://F3kRZMqi.kgLtb.cn
http://DFIAQMyP.kgLtb.cn
http://to2e7Mm5.kgLtb.cn
http://Z2PgyrV2.kgLtb.cn
http://KqAPiQR0.kgLtb.cn
http://zfR4kVHB.kgLtb.cn
http://e0WzbBZJ.kgLtb.cn
http://lidLs0Ty.kgLtb.cn
http://Avhj63qx.kgLtb.cn
http://ioA70B4n.kgLtb.cn
http://D4kiv1zs.kgLtb.cn
http://R79LpXR8.kgLtb.cn
http://yZJY5JOq.kgLtb.cn
http://CNMH1HOq.kgLtb.cn
http://60vG8HGH.kgLtb.cn
http://wnWaBlXq.kgLtb.cn
http://NdOFhAb4.kgLtb.cn
http://jKELEolV.kgLtb.cn
http://b7Kw179w.kgLtb.cn
http://CQvQSqTi.kgLtb.cn
http://XCGxqnol.kgLtb.cn
http://JmcFBaDv.kgLtb.cn
http://19kJtHnZ.kgLtb.cn
http://tASbdeS7.kgLtb.cn
http://ktvVDA3C.kgLtb.cn
http://YqPTOQwX.kgLtb.cn
http://1bZ631Lt.kgLtb.cn
http://QJpCa7ZT.kgLtb.cn
http://www.dtcms.com/a/367007.html

相关文章:

  • python中的import和from两种导入方式有什么区别
  • MyBatis核心技术全解
  • 标注工具labelimg使用简介
  • 用 Rust + Actix-Web 打造“Hello, WebSocket!”——从握手到回声,只需 50 行代码
  • 【Java EE进阶 --- SpringBoot】Spring IoC
  • 机器学习基础-day03-机器学习中的线性回归
  • GPT-5冷酷操盘,游戏狼人杀一战封神!七大LLM狂飙演技,人类玩家看完沉默
  • FastGPT源码解析 Agent工作流编排后端详解
  • Python基础(①④内存管理机制)
  • 脑卒中目标检测含完整数据集
  • Unity核心概率⑤:GameObject
  • 【Python办公】tkinter词云图生成器
  • 使用Qt Charts实现高效多系列数据可视化
  • 【数据可视化-106】华为2025上半年财报分析:用Python和Pyecharts打造炫酷可视化大屏
  • tsconfig.json的target和module详解
  • 无人机气象观测技术
  • 【开题答辩全过程】以 小众商户小程序为例,包含答辩的问题和答案
  • house (ai)
  • Dify 从入门到精通(第 75/100 篇):Dify 的实时流式处理进阶(高级篇)
  • 从质疑到真香:小白使用「飞牛NAS」+「节点小宝」的花式操作
  • 关于NET Core jwt Bearer Token 验证的大坑,浪费3个小时,给各位兄弟搭个桥。
  • 人工智能学习:传统RNN模型
  • PyTorch DDP 随机卡死复盘
  • JVM 类加载全过程
  • 关于IDEA构建Gradle项目时报错“contentRootData“ is null的一次排查
  • devcpp 5.11的详细安装步骤
  • 高效菜单管理页面:一键增删改查
  • jmeter压测工具使用详情
  • finally 与 return的执行顺序
  • Java String vs StringBuilder vs StringBuffer:一个性能优化的探险故事