目录
一、什么是put请求和delte请求?
- PUT 请求用于向服务器发送数据,以更新服务器上指定资源的内容。
- DELETE 请求用于请求服务器删除指定的资源。
二、为什么会用到put请求和delete请求?
PUT 请求:
- 实现完整的资源更新:当需要确保对资源进行全面、准确的更新,而不仅仅是部分修改时,PUT 请求能够确保服务器接收到完整的新数据来覆盖旧资源。
- 保持数据一致性:对于一些对数据一致性要求较高的场景,PUT 能够确保数据的完整性和准确性更新。
DELETE 请求:
- 资源清理和管理:当不再需要某个特定资源时,DELETE 请求能够有效地从服务器中移除它,以释放资源和保持数据的整洁性。
- 维护数据准确性:删除过时、错误或不再有效的资源,以确保系统中的数据始终是准确和有用的。
三、为什么put请求和delete请求会被拦截?
- 防止未经授权的修改和删除:PUT 请求用于更新资源,DELETE 请求用于删除资源。如果没有适当的授权和身份验证机制,恶意攻击者可能利用这些请求来篡改或删除重要的数据和资源,对系统造成严重破坏
- 防范 CSRF 攻击:跨站请求伪造(CSRF)攻击中,攻击者可能诱使用户在不知情的情况下发起 PUT 或 DELETE 请求。拦截这些请求可以降低 CSRF 攻击成功的风险
- 保护敏感数据:某些包含敏感信息的资源,为了防止意外或恶意的修改和删除操作,会对相关的 PUT 和 DELETE 请求进行拦截和严格的审查
- 防止批量操作风险:大量的 PUT 或 DELETE 请求可能会对系统性能和数据完整性产生影
- 合规和审计要求:某些行业和法规要求对数据的修改和删除操作进行严格的监控和记录。拦截这些请求可以更好地满足合规性,并进行必要的审计跟踪
四、解决方案
- 让网关关闭掉put请求和delete请求的拦截(不太现实)
- 通过虚拟请求来解决put和delete请求问题
1、更改前端请求:
找到前端统一的请求处理,将原put请求和delete请求转为post和get(以axios为例)
export function httpAction(url,parameter,method) {
let mm = method.toLowerCase() === 'delete'? 'get' : method.toLowerCase() === 'put'?'post': method.toLowerCase(); //将put转成post delete转成get
debugger;
return axios({
url: url,
method: mm, //请求换为虚拟请求
headers: {
'X-HTTP-Method-Override': method //将实际请求封装到请求头里边
},
data: parameter
});
}
2、更改后端接收:
由于前端对请求做了处理,实际的请求方式被放在了请求头中所以后端需要编写拦截器对请求进行相应的处理
package org.moreyou.config;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
/**
* @author NSB
*/
@Component
public class ChangeHttpMethodFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//获取前端真实的请求方式
String method = httpServletRequest.getHeader("X-Http-Method-Override");
// 如果修改和删除需要改变
if (HttpMethod.DELETE.name().equalsIgnoreCase(method) || HttpMethod.PUT.name().equalsIgnoreCase(method)) {
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpServletRequest) {
@Override
public String getMethod() {
return method.toUpperCase();
}
};
filterChain.doFilter(requestWrapper, servletResponse);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
//切记下边这两个一定要重写 不重写会导致tomcat启动异常
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作
System.out.println("Interceptor initialized");
}
@Override
public void destroy() {
// 销毁操作
System.out.println("Interceptor destroyed");
}
}