在我的开发机器 osx-sierra / apache 2.4.10(来自 brew)上,我在 VirtualHost 中有一个限制,允许无需密码访问 /api/,并且所有其他页面都需要使用以下代码的密码:
<Location />
AuthType Basic
AuthName "Access"
AuthUserFile /Users/xxxxxx/www/public/.htpasswd
Require expr %{REQUEST_URI} =~ m#^/api/*#
Require valid-user
</Location>
当我尝试在生产服务器上使用相同的指令 Debian-jessie / apache 2.4.29(来自 apt)执行此操作时,它不起作用,密码总是询问(chrome / safari / wget),我尝试了这些解决方案:
1/
<Location />
AuthType Basic
AuthName "Access"
AuthUserFile /home/xxxxxx/www/public/.htpasswd
Require expr %{REQUEST_URI} =~ m#^/api/*#
Require valid-user
</Location>
2/
<Location />
AuthType Basic
AuthName "Access"
AuthUserFile /home/xxxxxx/www/public/.htpasswd
Require expr %{REQUEST_URI} =~ m#^/api/.*#
Require valid-user
</Location>
知道为什么会有这些差异吗?
谢谢
答案1
我不确定为什么这在 osx-sierra / Apache 2.4.10 上有效,但在 Debian-jessie / Apache 2.4.29 上似乎不行。但是,作为一种解决方法,您可以使用另一种方式来实现这一点负面前瞻在<LocationMatch>
容器上,而不是使用 Apache 2.4 表达式。例如:
<LocationMatch "^(?!/api/.*$).*$">
AuthType Basic
AuthName "Access"
AuthUserFile /Users/xxxxxx/www/public/.htpasswd
Require valid-user
</LocationMatch>
<LocationMatch>
现在,仅当 URL 未以 开头时,才会处理容器内的指令/api/
。(这也适用于 Apache 2.2)
答案2
这是指令不起作用的完整虚拟主机:
<VirtualHost *:80>
DocumentRoot /home/xxxxxx/www/public
ServerName xxxxxx.com
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, PUT, GET, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-so-resource, x-so-apikey, x-so-apisecret, x-token, Authorization, Content-Type"
<Directory /home/xxxxxx/www/public>
php_value include_path "/home/xxxxxx/libs/ZendFramework-1.11.11/library"
Options +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
ServerSignature Off
AddDefaultCharset UTF-8
php_value short_open_tag 0
SetEnv APPLICATION_ENV development
<Location />
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Location>
<LocationMatch "^(?!/api/.*$).*$">
AuthType Basic
AuthName "Access"
AuthUserFile /home/xxxxxx/www/public/.htpasswd
Require valid-user
</LocationMatch>
ErrorLog /var/log/apache2/xxxxxxxx-error.log
CustomLog /var/log/apache2/xxxxxxxx-access.log combined
答案3
为什么要把它弄得这么复杂而不是直接把它做好呢?
<Location />
AuthType Basic
AuthName "Access"
AuthUserFile /home/xxxxxx/www/public/.htpasswd
Require valid-user
</Location>
<Location /api>
Require all granted
</Location>
还要注意,您之前的目录(documentroot 目录)指令混合了 2.2.x 和 2.4.x 指令可能会把一切都搞砸。
一团糟:
Order allow,deny
Allow from all
Require all granted
正确的做法是:
Require all granted
- 请务必删除 2.2. 指令并卸载 mod_access_compat,以确保您所做的是获得意外结果的秘诀。还请考虑您可能拥有的 .htaccess 文件可能会因设置 AllowOverride all 而影响结果,如果您是网站管理员,最好不要使用 AllowOverride all。