如何告诉 .htaccess 仅允许对 index.php 和 app/dist/* 文件夹的请求?

如何告诉 .htaccess 仅允许对 index.php 和 app/dist/* 文件夹的请求?

这是当前文件夹:

/app
  /dist
    /index.html
    /index.css
    /index.js
  /src
    /configurations.json
/index.php
/configurations.php

我到处都有敏感数据:

  • app/src/...
  • /...

我希望用户只能访问:

  • index.php
  • app/dist/whateverfile.whateverformat

dist文件夹可以改变,所以我必须让他们静态访问这个目录,这样我就不必列出每个文件。

用这种语法该怎么做呢.htaccess

我有这个配置,可以让我访问index.php。但不知道该如何实现文件夹dist...

Options -Indexes
DirectoryIndex index.php

<FilesMatch ".*">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

<Files index.php>
    Order allow,deny
    Allow from all
    Satisfy All
</Files>

<Files "">
    Order allow,deny
    Allow from all
    Satisfy All
</Files>

提前致谢。

答案1

<Files>指令<FilesMatch>仅针对文件,而不是目录。如果您有权访问服务器配置,那么您可能会使用容器<Directory>

使用 mod_rewrite

您可以使用 mod_rewrite来.htaccess限制对/index.php或之外的任何内容的访问/app/dist/

例如:

RewriteEngine On

RewriteRule !^(index\.php$|app/dist/) - [F]

/index.php对于任何未启动或未启动的请求,上述代码将返回 403 Forbidden 错误/app/dist/。如果您希望返回 404 错误,请更改FR=404

正则表达式的前缀!否定了正则表达式。请注意,RewriteRule 图案不以斜线开头。

如果您只想对映射到实际文件或目录的请求响应 403(否则响应 404),则添加几个检查文件系统的条件(但请注意,文件系统检查相对昂贵,因此除非您需要它们,否则不要使用它们)。例如:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule !^(index\.php$|app/dist/) - [F]

仅当请求的 URL 不在允许的“组”中时映射到文件或目录是RewriteRule执行的指令。

但是,我假设您的 URL 实际上不包含index.php(是吗?),在这种情况下,用户请求/并且 mod_dir 发出内部子请求/index.phpDirectoryIndex)。在这种情况下,您需要将 设为index.php可选。

例如:

RewriteRule !^((index\.php)?$|app/dist/) - [F]

使用 Apache 表达式

或者,您可以使用 Apache 表达式(Apache 2.4)执行此操作

<If "%{REQUEST_URI} !~ m#^/((index\.php)?$|app/dist/)#">
    Require all denied
</If>

/对于任何不是或/index.php以 开头的URL 请求,上述响应为 403 /app/dist/

请注意Order,、、AllowDeny是较旧的 Apache 2.2 指令,在 Apache 2.4 上已正式弃用。


使用 mod_setenvif

另一种选择是使用 mod_setenvif 并在请求允许的 URL 路径之一时设置环境变量,并且仅在设置了此环境变量时才允许访问。

例如:

SetEnvIf Request_URI "^/((index\.php)?$|app/dist/)" ALLOWED
Require env ALLOWED

ALLOWED如果请求任何允许的 URL 路径,则上述代码会设置环境变量。Require然后,该指令要求设置此环境变量以授予访问权限,否则将返回 403。

答案2

如果这是您的主要问题:“我到处都有敏感数据”

最简单、最可靠的解决方法是将敏感信息移至 Web 根目录之外的某个地方……

DocumentRoot考虑一个仅包含没有其他数据的Web 根目录(您的) index.php
,您不需要任何复杂的规则来保护它......


然后您可以使用例如Alias指令(最好在您的主服务器配置文件中,或者如果您更喜欢.htaccess在您的 Web 根目录中的文件)或 mod_rewrite 规则将 URI 映射到存储在您的 DocumentRoot 目录/文件之外的目录中的文档,以专门允许访问。

IE

.
`-- some-path
    |-- app
    |   `-- dist
    |       |-- index.css
    |       |-- index.html
    |       `-- index.js
    |-- src
    |   `-- configurations.json
    `-- www.example.com
        |-- .htaccess
        `-- index.php

你的主要 Apache 配置定义/some-path/www.example.comDocumentRootwww.example.com。然后
可以.htaccess是这样的内容,将 /some-path/app/ 目录及其所有内容公开为 URI 路径http://www.example.com/app/

# /some-path/www.example.com/.htaccess
# exposes/some-path/app/ directory  as the URI path `http://www.example.com/app/`

Alias "/app" "/some-path/app"

或者在指令中使用更具体Alias "/app/dist" "/some-path/app/dist"或更有创意的正则表达式AlaisMatch

答案3

以下是具体方法:

Options -Indexes
ServerSignature Off 
DirectoryIndex index.php

RewriteEngine on
RewriteRule ^ui(/)?$ app/dist/index.html [QSA,END,NC,L]
RewriteRule ui/(.*) app/dist/$1 [QSA,END,NC,L]
RewriteRule !(ui/.*) index.php [QSA,END,NC,L]

注意END每次匹配后的标志。此标志是模拟典型if-else语法所必需的。但官方文档中没有记录。

我最终转向了 Node.js。

相关内容