apisix配置http重定向到https

https://apisix.apache.org/docs/apisix/FAQ

更新

2021-12-20 下午收到 apisix 社区人员反馈,看到这篇博客,已经提了 bug issue.
后续官方解决后,仍然按官方给出的解决方案来配置。

bug: Using proxy-rewrite to overwrite the request header x-forwarded-proto failed

背景

一般网站在使用https协议之后,都会在访问 http 站点的时候,自动 301 重定向到 https,而且百度搜索资源收录也要求你在启用https的时候,保证http能够正确的301到https,那么使用 APISIX 该怎么实现呢

开整

一般我们遇到问题,都会去百度/谷歌或官网搜一下,那么官网给出了三种方案:

  • 1 直接使用 redirect 插件(试用后没生效)
1
2
3
4
5
6
7
8
9
10
curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"host": "foo.com",
"plugins": {
"redirect": {
"http_to_https": true
}
}
}'

尝试这种方法后,浏览器就一直在https重定向: ERR_TOO_MANY_REDIRECTS,应该是插件自身的问题

  • 2 使用 路由规则 vars + redirect 插件(试用仍无效)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"host": "foo.com",
"vars": [
[
"scheme",
"==",
"http"
]
],
"plugins": {
"redirect": {
"uri": "https://$host$request_uri",
"ret_code": 301
}
}
}'

尝试这个方式后,遇到两个错误:

  • 404 Route Not Found

    scheme == https 时,发现了404的问题(具体是哪个忘记了)

    经不断尝试,大概得出 404 的原因是 route 规则 vars 没有生效,按官方的说法是按 nginx 变量来配置,用 scheme 来判断请求协议理论上是没毛病的,真正原因暂时不管

  • ERR_TOO_MANY_REDIRECTS

    和第一种方法的错误一样,从 json 上对比,其实只比第一种方法多了一个 vars

  • 3 serverless 插件(没有试过,先忽略)

点击查看详细内容
1
2
3
4
5
6
7
8
9
10
curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": ["return function() if ngx.var.scheme == \"http\" and ngx.var.host == \"foo.com\" then ngx.header[\"Location\"] = \"https://foo.com\" .. ngx.var.request_uri; ngx.exit(ngx.HTTP_MOVED_PERMANENTLY); end; end"]
}
}
}'
  • 最终方案

既然我们相信 Apache 出品,必属精品,那就从官方的方案中改进一下方案,最终想起 nginx 中有一个属性可以拿到请求协议:http_x_forwarded_proto,在第二种方案基础上修改之后,果然成功!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"host": "foo.com",
"vars": [
[
"http_x_forwarded_proto",
"==",
"http"
]
],
"plugins": {
"redirect": {
"uri": "https://$host$request_uri",
"ret_code": 301
}
}
}'

关于 X-Forwarded-Proto 的含义:用来确定客户端与代理服务器或者负载均衡服务器之间的连接所采用的传输协议(HTTP 或 HTTPS)。

最后

果然技术是需要长时间的积累,然后在关键时刻才能起大作用。

refer

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注