👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练”
《互联网高频面试题》:面朝简历学习,春暖花开
《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题
《精进 Java 学习指南》:系统学习,互联网主流技术栈
《必读 Java 源码专栏》:知其然,知其所以然

👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本
来源:blog.youkuaiyun.com/aiwangtingyun
/article/details/126640870
API 接口防篡改、防重放攻击常见方案。
API 接口暴露问题
由于提供给第三方服务调用的 API 接口需要暴露在外网中,并且接口上提供了具体的请求地址和请求参数,那么,接口就有可能被人抓包拦截并对请求参数进行修改后再次发起请求 ,这样一来可能会被盗取信息,二来服务器可能会受到攻击。
为了防止这种情况发生,需要采取安全机制措施进行防范,方法有多种,比如:
接口采用
https的传输方式,https 传输的数据是经过了加密的,可以保证不被篡改;项目后台采用安全的验证机制,比如采用参数加密 和请求时间限制 来防止参数篡改和二次投放(*我们以这种方式为案例进行讲解 *)。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
防止接口参数篡改
为了防止参数被抓包篡改参数,我们可以对参数进行加密。具体方式如下:
前端使用约定好的秘钥 对传输参数进行加密,得到签名值 sign1,并且将签名值存入headers,然后发送请求给服务端;
服务端接收客户端的请求后,在过滤器 中使用约定好的秘钥对请求的参数再次进行签名,得到签名值 sign2;
最后对比 sign1 和 sign2 的值,如果相同,则认定为合法请求,如果不同,则说明参数被篡改,认定为非法请求。
防止接口重投放
重投放 或者叫二次投放 ,指的是接口被人拦截篡改参数后重新发送请求。防止重投放的方案是:基于 timestamp 对参数进行签名 ,具体的实现是:
每次 http 请求,headers 都加上 timestamp 时间戳,并且 timestamp 和请求的参数一起进行数字签名;
服务器收到请求之后,先判断时间戳参数与当前时间是否超过了60s(这个可以自定义配置,一般黑客从抓包到重放的耗时远远超过了60s),如果超过了则提示签名过期;
如果黑客修改了 timestamp 参数,则 sign 参数对应的数字签名就会失效,因为黑客不知道签名秘钥,没有办法生成新的数字签名(前端一定要保护好秘钥和加密算法 )。
当然也有一些其他方案,比如:数据库唯一主键 + 乐观锁;防重 Token 令牌,跳转前端表单页面时,设置一个 UUID 作为 token,并设置在表单隐藏域。
同时,前端页面表提交钮置灰不可点击 + js 节流防抖。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
核心思路代码设计
代码思路主要是通过创建过滤器,对参数进行签名验证,核心过滤器代码如下:
@Component
@Slf4j
public class SignAuthFilter implements Filter {
@Autowired
private SignAuthProperties signAuthProperties;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("初始化 SignAuthFilter...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 过滤不需要签名验证的地址
String requestUri = httpRequest.getRequestURI();
for (String ignoreUri : signAuthProperties.getIgnoreUri()) {
if (requestUri.contains(ignoreUri)) {
log.info("当前URI地址:" + requestUri + ",不需要签名校验!");
chain.doFilter(request, response);
return;
}
}
// 获取签名和时间戳
String sign = httpRequest.getHeader("Sign");
String timestampStr = httpRequest.getHeader("Timestamp");
if (StringUtils.isEmpty(sign)) {
responseFail("签名不能为空", response);
return;
}
if (StringUtils.isEmpty(timestampStr)) {
responseFail("时间戳不能为空", response);
return;
}
// 重放时间限制
long timestamp = Long.parseLong(timestampStr);
if (System.currentTimeMillis() - timestamp >= signAuthProperties.getTimeout()*1000) {
responseFail("签名已过期", response);
return;
}
// 校验签名
Map<String, String[]> parameterMap = httpRequest.getParameterMap();
if (SignUtils.verifySign(parameterMap, sign, timestamp)) {
chain.doFilter(httpRequest, response);
} else {
responseFail("签名校验失败", response);
}
}
/**
* 响应错误信息
*/
private void responseFail(String msg, ServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
out.println(msg);
out.flush();
out.close();
}
@Override
public void destroy() {
log.info("销毁 SignAuthFilter...");
}
}
这里我们可以在 yml 配置文件中进行配置重放超时时间和不过滤的 URI 地址:
sign:
# 签名超时时间
timeout: 60
# 允许未签名访问的 url 地址
ignoreUri:
- /swagger-ui.html
- /v2/api-docs
然后编写配置类:
@Data
@ConfigurationProperties(prefix = "sign")
public class SignAuthProperties {
/**
* 签名超时时间
*/
private Integer timeout;
/**
* 允许未签名访问的 url 地址
*/
private List<String> ignoreUri;
}
在签名的校验代码中,省略了具体的校验方法,因为不同的加密方式对应不用的校验方法,所以这里只提供一个代码思路,只要前后端约定好如何进行加密即可 。
本文我解释了多种方法,只实现了其中的一种。大家根据个人爱好和业务场景,选择不同的方案。
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。





文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
3717

被折叠的 条评论
为什么被折叠?



