http - 使用 .htaccess 将 http 重定向到 https 时,某些网址会出现奇怪的 401 错误

标签 http .htaccess mod-rewrite https http-status-code-401

好的,这是第 7 天尝试寻找为什么会出现 401 错误的答案...

现在, 根文件夹中的 .htaccess 仅包含 3 个字符串(已简化)并且项目中没有更多的 .htaccess 文件:

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

因此,它将所有请求重定向为 https。它适用于任何 url,甚至适用于/administration 目录。

所以,

http://mydomain.com

成为

https://mydomain.com

如果输入了 https://mydomain.com,则没有重定向。

http://mydomain.com/administration/index.php

成为

https://mydomain.com/administration/index.php

如果输入了 https://mydomain.com/administration/index.php,则没有重定向。

明白了,下面就是问题了。

我希望/administration 目录受密码保护。我的共享主机控制面板允许在不手动创建 .htaccess 和 .htpasswd 的情况下保护目录(您选择要保护的目录,创建用户名和密码,然后自动创建 .htaccess 和 .htpasswd)。因此,.htaccess 出现在/administration 文件夹中。 .htpasswd 出现在其他地方,.htpasswd 的路径是正确的,一切看起来都是正确的(它的工作方式与手动创建它的方式相同)。所以,项目中有2个.htaccess文件,一个在根目录下,一个在/administration目录下(带.htpasswd在目录下,.htaccess知道在哪)。

创建密码后, 结果是:

你输入:

https://mydomain.com/administration/index.php

然后它要求输入密码。 如果输入正确, https://mydomain.com/administration/index.php 显示。 结果:效果完美。

但是,如果你输入 http://mydomain.com/administration/index.php(是的,http,没有 S) 然后不是重定向到相同的 https 页面, 它重定向到

https://mydomain.com/401.shtml (starts with httpS)

由于未知原因甚至不询问密码。 为什么?

我已经就这个问题联系了客户支持,他们确定问题出在 .htaccess 文件中,并且他们没有修复 .htaccess 文件(很明显,他们没有,我不介意)。

为什么会这样? 我是不是忘了在 .htaccess 文件中放置一些标志或一些选项来更改默认设置?

P.S.为文件夹/administration 手动创建 .htaccess 和 .htpasswd(不是从托管控制面板)会导致相同的 401 错误,如果输入的不是 https,而是 http。

问题只出现在/administration 目录的 URL 上。

谢谢。

最佳答案

尝试改用它。不是 L 和 R 标志。

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

同时先清除浏览器缓存,以删除旧的不正确的重定向。

如果这不起作用,请尝试使用它。

RewriteCond %{HTTPS} !on
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ ([^\ ]+)
RewriteRule ^ https://%{HTTP_HOST}%2 [L,R=301]

我觉得写它有点不好,因为在我看来它有点老套。

编辑 似乎第二个选项解决了这个问题。所以这里是关于它为什么起作用的解释。

认证模块在重写模块之前执行。因为第一次请求页面时没有发送用户名和密码,认证模块在内部“重写”请求 url 为 401 页面的 url。在这个 mod_rewrite 出现之后,%{THE_REQUEST} 现在包含 401.shtml 而不是原来的 url。因此,生成的重定向包含 401.shtml,而不是您想要的 url。

要获取原始(不是“重写”)的 url,您需要从 %{THE_REQUEST} 中提取它。 THE_REQUEST 的格式为 [requestmethod] [url] HTTP[versionnumber]。 RewriteCond 仅提取中间部分 ([url])。

为了完整起见,我在第二个解决方案中添加了 [L,R=301] 标志。

关于http - 使用 .htaccess 将 http 重定向到 https 时,某些网址会出现奇怪的 401 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9239033/

相关文章:

java - 是否可以使用 HTTP POST 下载文件?

regex - mod_rewrite 正则表达式中的转义句点 (.) 字符

url - mod_rewrite - 将查询字符串转换为路径

.htaccess - 如何使用Mod_Rewrite将用户重定向到Mobile子目录?

rest - 应该从 CQRS 命令的 API 返回什么?

php - 如何在一个提交按钮上禁用 JS 的情况下为访问者执行两个 POST 请求?

java - 为什么 Chrome 不渲染从套接字输出流获取的页面? java

javascript - 通过在 react-router 的地址栏中输入它的地址直接访问路由器

php - 试图重写样式表的路径

apache - 在 RewriteCond 条件模式中使用变量