Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nginx 请求头配置导致的 admin 页面重定向错误 #2254

Closed
3 tasks done
8Q757 opened this issue Jul 16, 2022 · 10 comments · Fixed by #2259
Closed
3 tasks done

Nginx 请求头配置导致的 admin 页面重定向错误 #2254

8Q757 opened this issue Jul 16, 2022 · 10 comments · Fixed by #2259
Assignees
Labels
kind/improvement Categorizes issue or PR as related to a improvement.
Milestone

Comments

@8Q757
Copy link

8Q757 commented Jul 16, 2022

检查清单

是什么版本出现了此问题?

1.4.16

使用的什么数据库?

MySQL 5.7

使用的哪种方式部署?

Docker

在线站点地址

No response

发生了什么?

背景

nginx 与 halo 在 docker 的同一网桥中,并且 nginx 配置为:

add_header       X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-Host   $host;
proxy_set_header X-Forwarded-Port   $port;
proxy_set_header X-Forwarded-For    $remote_addr;
proxy_set_header X-Real-IP          $remote_addr;
proxy_pass       $forward_scheme://$server:$port$request_uri;

其中,$server 配置为 halo 的容器名字,$port 配置为 halo 应用及容器对外暴露的端口号8090。

安装完成后,访问 example.com 没问题,但登录后台时候,example.com/admin 会跳转到 example.com:8090/admin/index.html
多了个端口号8090,导致访问失败,但访问其他任何地址均无此问题。
根据后续排查,发现是 nginx 中带有 proxy_set_header X-Forwarded-Port $port;,去掉后可以解决该问题。

但在 #909 中,有部分用户由于使用非80端口则需要加上该配置。

解决

综上,于是去排查代码,定位到该问题是由于访问后台管理时的重定向导致。

@GetMapping("${halo.admin-path:admin}")
public void admin(HttpServletResponse response) throws IOException {
    String adminIndexRedirectUri =
            HaloUtils.ensureBoth(haloProperties.getAdminPath(), HaloUtils.URL_SEPARATOR)
                + INDEX_REDIRECT_URI;
    response.sendRedirect(adminIndexRedirectUri);
}

此处重定向中,仅重定向至目录,所以重定向到的域名默认为当前请求中的域名。
但在使用反向代理时候,halo 能获取到的域名是由网关(在上文中为 nginx 的配置决定的),导致没有带入端口号或者带入错误的端口号,重定向到了错误的地址。
为减少用户在 nginx 配置上的心智负担和错误成本,建议可以在重定向时候,获取当前博客的配置域名进行完整域名的重定向。
稍后我会提交PR,以解决此问题。

相关日志输出

No response

附加信息

No response

@ruibaby
Copy link
Member

ruibaby commented Jul 16, 2022

/assign @viticis

@ruibaby
Copy link
Member

ruibaby commented Jul 16, 2022

建议可以在重定向时候,获取当前博客的配置域名进行完整域名的重定向。稍后我会提交PR,以解决此问题。

但需要注意的是,如果使用者配置的域名无法访问(比如 https 证书失效),使用者想通过 IP:端口/admin 进入后台的话,这个时候可能也无法正常跳转到后台。必须直接访问 IP:端口/admin/index.html 才可以。

@8Q757
Copy link
Author

8Q757 commented Jul 16, 2022

建议可以在重定向时候,获取当前博客的配置域名进行完整域名的重定向。稍后我会提交PR,以解决此问题。

但需要注意的是,如果使用者配置的域名无法访问(比如 https 证书失效),使用者想通过 IP:端口/admin 进入后台的话,这个时候可能也无法正常跳转到后台。必须直接访问 IP:端口/admin/index.html 才可以。

是我考虑不周了😂,既然如此就不修改代码了,该 issue 可以关闭留待后人有类似问题时候能搜索到吧。

@8Q757
Copy link
Author

8Q757 commented Jul 16, 2022

不过我又想到一个问题,为什么不直接返回页面,而是用重定向呢?

@GetMapping("${halo.admin-path:admin}")
public String admin(HttpServletResponse response) throws IOException {
    String adminIndexRedirectUri =
            HaloUtils.ensureBoth(haloProperties.getAdminPath(), HaloUtils.URL_SEPARATOR)
                + INDEX_REDIRECT_URI;
        // response.sendRedirect(adminIndexRedirectUri);
    return adminIndexRedirectUri;
}

@ruibaby
Copy link
Member

ruibaby commented Jul 16, 2022

不过我又想到一个问题,为什么不直接返回页面,而是用重定向呢?

因为目前的方法是通过静态资源代理的方式代理到 admin 的构建资源目录,不是模板渲染。SpringMVC 的 Controller 返回 String 类型的数据应该是需要对应一个模板文件。

@ruibaby
Copy link
Member

ruibaby commented Jul 16, 2022

@viticis 不过也欢迎大家讨论出一个更加好的方案。

@8Q757
Copy link
Author

8Q757 commented Jul 16, 2022

不过我又想到一个问题,为什么不直接返回页面,而是用重定向呢?

因为目前的方法是通过静态资源代理的方式代理到 admin 的构建资源目录,不是模板渲染。SpringMVC 的 Controller 返回 String 类型的数据应该是需要对应一个模板文件。

我改成如上代码后是可以正常访问的,路径是 localhost:8090/admin#install,有时间我再具体测试下有没有问题,理论来说模板文件也是html🤣

@ruibaby
Copy link
Member

ruibaby commented Jul 18, 2022

/milestone 1.6.x

@f2c-ci-robot f2c-ci-robot bot added this to the 1.6.x milestone Jul 18, 2022
@ruibaby
Copy link
Member

ruibaby commented Jul 18, 2022

/kind improvement

@f2c-ci-robot f2c-ci-robot bot added the kind/improvement Categorizes issue or PR as related to a improvement. label Jul 18, 2022
f2c-ci-robot bot pushed a commit that referenced this issue Jul 19, 2022
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. 如果这是你的第一次,请阅读我们的贡献指南:<https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>。
1. If this is your first time, please read our contributor guidelines: <https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>.
2. 请根据你解决问题的类型为 Pull Request 添加合适的标签。
2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request.
3. 请确保你已经添加并运行了适当的测试。
3. Ensure you have added or ran the appropriate tests for your PR.
-->

#### What type of PR is this?

/kind improvement

<!--
添加其中一个类别:
Add one of the following kinds:

/kind bug
/kind cleanup
/kind documentation
/kind feature
/kind improvement

适当添加其中一个或多个类别(可选):
Optionally add one or more of the following kinds if applicable:

/kind api-change
/kind deprecation
/kind failing-test
/kind flake
/kind regression
-->

#### What this PR does / why we need it:

访问后台管理时使用重定向,在有反向代理且配置不完善的情况下,会导致重定向的域名发生错误。

https://spring.io/guides/gs/serving-web-content/
#### Which issue(s) this PR fixes:

<!--
PR 合并时自动关闭 issue。
Automatically closes linked issue when PR is merged.

用法:`Fixes #<issue 号>`,或者 `Fixes (粘贴 issue 完整链接)`
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
Fixes #2254

#### Special notes for your reviewer:
/cc @halo-dev/sig-halo 

#### Does this PR introduce a user-facing change?



<!--
如果当前 Pull Request 的修改不会造成用户侧的任何变更,在 `release-note` 代码块儿中填写 `NONE`。
否则请填写用户侧能够理解的 Release Note。如果当前 Pull Request 包含破坏性更新(Break Change),
Release Note 需要以 `action required` 开头。
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->

```release-note
修改后台管理页面为直接渲染而不是重定向,以更好的兼容反向代理
```
@robinoneway
Copy link

robinoneway commented Aug 17, 2022

@ruibaby 请问一下,我在内网使用IP:8090访问前端页面和后台都没问题,当我用花生壳做内网穿透,使用域名可以访问到前端页面,但是访问admin后台,就提示“该网页无法正常运作,xxx.com未发送任何数据”,不知道是花生壳的问题,还是我配置有问题?我是linux(raspberry)部署,halo是1.5.4版的,按照官网的Caddy2.x的配置也一样,前端各页面正常访问,一旦访问admin后台,就打不开

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/improvement Categorizes issue or PR as related to a improvement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants