本文已参与「新人创作礼」活动,一起开启掘金创作之路。
apisix配置http重定向到https
背景
一般网站在使用https协议之后,都会在访问 http 站点的时候,自动 301 重定向到 https,而且百度搜索资源收录也要求你在启用https的时候,保证http能够正确的301到https,那么使用 APISIX 该怎么实现呢
开整
一般我们遇到问题,都会去百度/谷歌或官网搜一下,那么官网给出了三种方案:
- 1 直接使用
redirect插件(试用后没生效)
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插件(试用仍无效)
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插件(没有试过,先忽略)
点击查看详细内容
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,在第二种方案基础上修改之后,果然成功!
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
-
这个文档里面是有
scheme的,但没有http-x-forwarded-proto