当Kong遇上redirect 302重定向

个人博客地址:http://www.ltang.me/2020/11/06/kong-302-problem/

在线上环境中,常常因为网络限制等,通过nginx做反向代理,将不同的服务通过同一个入口提供给请求方。

事情呢是这样的

为了方便配置和使用更丰富的功能,我们在测试环境使用了kong来做反向代理网关。使用浏览器访问http://ip_a:port_a/app,使用konga页面配置将请求转发到http://ip_b:port_b/app

在大多数场景下,工作良好。今天在配置新的应用时突然发生问题,现象如下:

  1. 浏览器访问http://ip_a:port_a/app
  2. 浏览器地址栏跳转到http://ip_b:port_b/app/...
  3. 由于本地与ip_b的网络不通,因此很显然请求失败了

观察network信息,可以发现,这是因为在请求ip_a:port_a时,后台返回了一个302重定向请求,因此浏览器按照返回的Location地址发起新的请求。那么解决这个问题的关键在于让重定向的地址依然是ip_a:port_a,通过有网络权限的kong所在的服务器来转发请求报文。

Nginx的解决办法

假如我们使用的是nginx,那么可以使用关键字proxy_redirect来将302重定向请求的Location地址修改为我们想要的代理地址,关键配置如下

server {
    listen       port_a;
    location /app {
       proxy_pass http://ip_b:port_b/app;
       proxy_redirect http://ip_b:port_b/app/ http://ip_a:port_a/app/;
    }
} 

如上配置,proxy_redirect会将302返回报文中的Location http://ip_b:port_ b/app/...修改为http://ip_a:port_a/app/...再返回给请求端。

Kong下的解决办法

Kong其实就是加强版的nginx嘛,既然nginx可以配置,那Kong肯定也行。

然而,搜索了一下,发现Kong的设计者这么回复:

Kong的设计理念对UI和重定向并不友好,实际上,他并不建议使用kong来作为网站的反向代理吧啦吧啦…

总之,它更适合于作为后台接口间的报文转发网关。所以,你想直接使用konga等页面配置来实现proxy_redirect的功能,那是不行滴。

再谷歌一下,发现其实很多人都遇到同样的问题,有同样的需求。主要参考了这个Issue找到的解决方案:https://github.com/Kong/kong/issues/3503

kong确实是个加强版的nginx,我们在Kong服务器上去找,其实是能找到nginx.conf这个配置文件的(还有nginx-kong.conf),但是与我们熟悉的配置不同,这里的nginx.conf并不是直接配置就可以用上了,因为它实际上是由nginx.lua(nginx_kong.lua)脚本生成出来的。即使你修改了配置文件中的内容,重启kong的时候,又会重新生成nginx的配置文件,将你的配置覆盖。

因此,我们去观察nginx.lua以及nginx_kong.lua脚本文件,在它写配置的模板的合适的地方,加上我们的proxy_redirect配置即可。添加保存后,重启kong,再去看新生成的nginx配置文件,就可以发现已经修改了,再去请求http://ip_a:port_a就不会被重定向到ip_b:port_b去了。

你当然可以直接写死如

proxy_redirect http://ip_b:port_b/app/ http://ip_a:port_a/app/;

但这样也可能觉得太死板,以后增加个ip_a转到ip_c的,又要增加个配置。因此,可以考虑将路径中的host参数化,充分利用nginx的路径规则匹配能力,比如

proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值