问题来源
为了解决CSRF跨站请求伪造,防止接口被恶意攻击
解决办法
验证HTTP请求的Referer是不是本服务器链接过来的
客户端或者浏览器在发送请求的时候 都会在请求头存在一个来源指向
Referer 就是当前服务的来源指向
如果是地址栏是 这样的 http://127.168.1.2:8000/index.thml
那么Referer 服务来源也是 http://127.168.1.2XXXXXXXXXX
发现被黑客篡改 关于篡改原因请看这篇文章 http请求头中Referer的含义和作用
本文重点不是讲这个原理
我这边写了一个对 http请求头中referer中的判断
String serverName = request.getServerName();
String referer = request.getHeader("Referer");
if (StringUtils.isNotEmpty(referer)){
if (!referer.contains(serverName)){
return false;
}
}
这段代码就是如果发现有伪造的请求过来 那么就直接返回false网关就不会继续转发服务
这个是写在网关里面的一个过滤器的 奇怪就是在本地 我的serverName 获取 与 referer 中所包含的地址是一样的。
但是放到测试环境就一直返回false
然后去服务器一看
日志显示 ---- 服务名:127.0.0.1,来源信息:https://101.168.202.1:8080/XXX
request.getServerName() 获取出来的是 127.0.0.1 但是请求头中的来源却是真实的IP
这样肯定不包含在内 所以就一直会是false
分析了好长一段时间 才发现 原来是测试环境有nginx 而本地是没有的
nginx反向代理的都是127.0.0.1 所以request.getServerName() 获取就是127.0.0.1 要想让request.getServerName()获取真是的IP 那就需要在nginx配置文件加上
server{
proxy_set_header Host $host; # 这样一行配置
}
proxy_set_header Host $host;
这个的意思是 这一行的作用是把原http请求的Header中的host字段也放到转发的请求里。
这样 就能保证nginx发送网关的时候 request.getServerName() 获取的就是你服务的真正的名字 而不是代理的127.0.0.1
我加上之后重新启动nginx之后
日志显示 ---- 服务名:101.168.202.1,来源信息:https://101.168.202.1:8080/XXX
这样就对了
关于proxy_set_header Host $host; 的详细用法 这里不做描述 百度上有很多。