htaccess 将文档根目录更改为 /public 并防止 /public 被使用

htaccess 将文档根目录更改为 /public 并防止 /public 被使用

我正在托管一个节点应用程序,我的文件夹结构如下:

mydomain.com
--index.js
--package.json
--public\test.txt

我想将其public视为我的文档根目录并且不允许访问其上方的任何内容,例如package.json

我目前正在使用.htaccess来更改“文档根目录”:

RewriteCond %{REQUEST_URI} !public/
RewriteRule (.*) /public/$1 [L]

这工作正常,我可以访问http://example.com/test.txt,但这也意味着http://example.com/public/test.txt也可以工作。

如何防止public直接在URL中使用而仅在后台使用?

我尝试添加RewriteRule ^public/ - [L,R=404]到末尾,但最终所有内容都返回 404。

答案1

需要澄清的是,您实际上并没有在这里更改文档根目录,而是使用 URL 重写有效地隐藏了子目录。要实际更改文档根目录,您需要更改DocumentRoot服务器配置中的指令(如评论中所述) - 这将产生其他影响(您的节点应用程序可能依赖于DocumentRoot设置的)。

RewriteCond %{REQUEST_URI} !public/
RewriteRule (.*) /public/$1 [L]

检查是否存在“public/”任何地方在请求的 URL 路径中,这实际上不是您所需要的。但是,RewriteCond此处不需要该指令。您应该检查 URL 路径中的RewriteRule 图案。 例如:

 RewriteRule !^public/ /public%{REQUEST_URI} [L]

请注意,REQUEST_URI服务器变量包含斜线前缀。(这也许就是为什么你删除了条件模式才能让它“工作”?)

我尝试添加RewriteRule ^public/ - [L,R=404]到末尾,但最终所有内容都返回 404。

这是正确的想法,然而,这本身也会改变重写URL(通过其他指令)。您只需定位直接请求。有几种方法可以做到这一点。我更喜欢检查REDIRECT_STATUS环境变量,即空的最初设置为“200”,第一次成功重写后设置为“200”。例如:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^public($|/) - [R=404]

($|/)- 请注意,我还将尾部斜杠设为“可选”,因为它将匹配publicpublic/(使用交替) 访问裸目录时。这是为了避免 mod_dir 首先发出 301 重定向以在目录上附加尾部斜杠,然后再发送 404 以响应重定向的(第二个)请求。交替(字符串结尾或者斜线)确保public/<foo>匹配,但public<foo>如果您的 URL 以“public”开头(例如/public-enemy),则不匹配。

使用非 3xx(或 2xx)状态代码时,无需该L标志,因为它默示

总之:

# Block direct requests to the "public" subdirectory
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^public($|/) - [R=404]

# Rewrite all requests that are not already for the "public" subdirectory
RewriteRule !^public/ /public%{REQUEST_URI} [L]

请注意,阻止(404)指令应该放在第一位。

相关内容