问题背景说明:
某系统发布的Webservice,经过API网关Kong代理后发现WSDL文件无法查看。
经测试发现原因是因为Kong身份验证的需要,在原url增加了apkikey=xxx这样的参数,如:
http://www.companya.com/app/services/orderDataService?wsdl&apkikey=xxx
该系统处理增加参数的请求时,出现下面的错误信息:
Invalid SOAP request.
解决思路:
在不修改应用程序代码的情况,想办法在nginx层做处理,将请求中apikey=xxx的部分过滤掉,再由tomcat服务器处理。
最终测试成功的nginx配置:
location /api { if ($query_string ~ ^(.*)&apikey=(.*)) { set $p $1; rewrite ^ $p? last; } proxy_pass http://tomcat_cluster; }
代码虽然看上去很简单,但由于对nginx的配置写法不熟悉,还是费了不少劲,有几个要点:
1. location的匹配对象,只是uri本身,不包括?之后的参数,如果使用的话用$query_string变量。
2. 代码第3行代码是必须的,因为rewrite本身也使用了正则匹配,如果直接使用$1的话,引用的rewrite匹配的结果。
3. 代码第4行$p后面的分号,也是必须,否则nginx会自动将uri之后的参数,附加到rewrite后的地址,在目前的这个配置下造成循环处理报错。
4. rewrite在最后一个参数,有4个可选项,含义如下:
last 相当于发起一个新的请求,nginx会重现根据location指令进行匹配处理
break 直接使用当前资源,不再执行location里余下的语句
permanent HTTP 301重定向
redirect HTTP 302重定向
前两个浏览器中的url地址不变,后两个会变为rewrite后的地址
参考资料: Nginx的rewrite指令官方文档