15

我的开发设置:Mac OSX 10.7.4 / Apache 2.2.21 / PHP 5.3.10

我希望根据开发与实时环境向我的 .htaccess 文件添加条件逻辑。例如,我想在实时服务器上进行身份验证,而不是在开发服务器上进行身份验证。我在我的httpd.conf

SetEnv DEV 1

我已经确认这个 var 是通过检查phpinfo()的输出来设置的。然后在我的.htaccess文件中

<IfDefine !DEV>
  AuthType Basic
  AuthName "password protected"
  AuthUserFile /path/to/.htpasswd
  Require valid-user
</IfDefine>

...但仍然提示我在本地开发人员上输入密码。看来该DEV变量不可用于.htaccess。我确实AllowOverride All设置了我httpd.conf的文档根目录。有任何想法吗?

4

6 回答 6

22

我刚解决这个问题大约 4 个小时,我相信我已经有了最终的答案,并且可以为大家总结如何解决这个特别痛苦的问题。

我正在使用带有 Apache 2.2x 和 Php 5.3 的 Windows 7 Home Premium 作为我的开发机器。我也想要一个DEV环境变量,我可以在我的 .htaccess 文件中使用它来关闭重写和其他在我的开发环境中无效但对我的生产环境至关重要的指令。

我的 .htaccess 文件如下所示;

<IfDefine !__DEV__>
    AddType application/x-httpd-php53 .php
</IfDefine>

HostGator 告诉我,为了拥有 php 5.3,我需要像这样修改我的 htaccess 文件以启用它,否则我只有 php 5.2。但是我已经在我的开发机器上安装了它,所以当我在本地查看它时,这个指令导致我的客户网站崩溃。我将要解释的所有内容都允许我在我的 Git 存储库中保留一个 .htaccess 文件,该文件在两个位置都可以使用。

首先,让我清理/总结一下我在网上搜索使用 IfDefine 和 SetEnv 解决此问题的方法时学到的所有东西;

  1. Apache 中的 IfDefine 指令,Only,ONLY,当我说只有我的意思是 ONLY 时,它响应在命令行传递的参数。让我稍微强调一下。只有命令行!
  2. SetEnv 和 SetEnvIf,是两个完全不同的东西。一个(SetEnv)用于 conf 文件,设置在 SERVER START TIME 设置的环境变量(特定于 apache)。SetEnfIf 在 REQUEST TIME 使用,仅用于根据 REQUEST 变量确定要设置的内容。
  3. IfDefine 指令不读取由 SetEnv 或 SetEnvIf 设置的变量。时期。没有争论,没有问题,没有“但我认为……”没有。没有,所以克服它。

简短的回答是否定的,你不能只在 httpd.conf 中使用“SetEnv DEV 1”,然后在你的 .htaccess 文件中使用 IfDefine 来检测它,根据编程逻辑的语法和性质,这看起来很直观和合理我们习惯了。回想一下,我们实际上并没有编程任何东西,这些是配置文件,当然它们不符合这种期望,仅仅是因为它们看起来应该如此。

答案

所以这意味着我必须弄清楚如何将启动参数添加到 Apache,对于 Linux 专家来说,答案是现成的,你只需将正确的东西添加到envvars文件中,但是对于我们这些可怜的windows迷怎么办?

好吧,对于 Windows 用户来说,它变得更有趣,原因如下:

  1. Windows 不允许您在 Apache2.2 的服务配置中永久添加启动参数(它不起作用,不要尝试,我已经做过一百万次了,相信我)。这是真的,如果你进去尝试输入自己的参数,它只会工作一次,然后下次打开对话框时参数字段为空。我不知道为什么会这样,但似乎这些参数是为了测试,而不是永久修改。
  2. 安装 Apache 后,它会在开始菜单中创建“开始”、“停止”和“重新启动”快捷方式,并安装 Apache 服务监视器。但是开始菜单中的快捷方式使用的启动参数与 apache 服务监视器使用的启动参数不同。因此,如果您使用这些方法的组合启动/停止 apache,您将获得不同的结果,具体取决于您使用的方法。但是,您可以将 -D "__DEV__" 放在开始菜单快捷方式中,它会起作用!

解决问题的步骤

在 Windows 开发环境中永久且通用地设置一个 __DEV__ 环境变量,您可以在 .htaccess 文件中使用 IfDefine 引用该环境变量,无论您使用服务或开始菜单中的快捷方式启动 Apache 还是使用 NET START/STOP 在命令行,执行以下操作:

  1. 打开开始菜单快捷方式的属性并提取您找到的用于启动 Apache 的命令。我的是;"C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -w -n "Apache2.2" -k start

  2. 修改它以包含新的 -D __DEV__ 变量,该变量必须在 httpd.exe 之后立即开始;"C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -D "__DEV__" -w -n "Apache2.2" -k start

  3. 您的开始菜单快捷方式现在将使用您的 dev 变量启动 apache。

  4. 转到命令行(以管理员身份)

  5. 类型:net stop apache2.2(或任何你的服务名称是 apache)

  6. 现在在命令行中输入(或复制粘贴)与上面开始菜单快捷方式中使用的命令相同的命令,但对其进行以下更改;"C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -D "__DEV__" -w -n "Apache2.2" -k config

  7. 请注意单词start更改为config。这个神奇的命令所做的是将您在屏幕上看到的设置保存到与 Windows 中的服务一起存储的设置中。点击输入。从现在开始,无论何时启动服务、Apache 服务监视器启动服务或 windows 启动服务,都会传递您的变量。

对不起大家的小说,我希望它可以帮助其他一些疲惫的灵魂来总结和解释所有这些信息,我知道它会对我有所帮助!:D

于 2012-09-07T18:13:47.403 回答
6

我的第一个答案的另一个选择是使用 Allow 指令。

看:http ://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#allow

Order deny,allow
Deny from all
AuthType Basic
AuthName "password protected"
AuthUserFile /path/to/.htpasswd
Require valid-user
Allow from env=DEV
Satisfy Any

这只会检查 DEV 是否存在而不是值,这就是 apache 的工作方式。将“允许”替换(或添加)“允许来自 127.0.0.1”以使您的本地主机始终处于开发模式。

这表明任何条件都是可接受的,其中条件是:密码或来自 127.0.0.1。如果你在你的本地主机上开发,你可以使用 127.0.0.1,或者只是用你开发的任何 ip 替换它。这不需要包装在任何东西中,只需放在您的 htaccess 文件中即可。我使用虚拟主机,所以我会把它放在那里。

来源(我将其更改为查看您的原始代码): http ://www.askapache.com/htaccess/apache-authentication-in-htaccess.html#allow-conditional

于 2012-06-27T06:07:33.280 回答
4

2年过去了,我遇到了类似的问题。具体来说,我们正在自动部署到 AWS OpsWorks 堆栈,并且无法控制 .htpasswd 文件的放置(用于在开发过程中隐藏工作)。

我们最终的工作解决方案是这样的(Apache 2.2.25):

# check the host against a regex, defining env=DEV if it matches
# this guy matches localhost, dev.project and 10.1.X.X
SetEnvIfNoCase Host "^(localhost|dev\.project|10\.1(\.\d+){2})$" DEV

AuthType Basic
AuthName "Restricted"

# auth file location, in our case defined by an AWS OpsWorks auto-deployment
# this only gets loaded if the regex above doesn't match, which is handy
AuthUserFile /srv/www/project/current/.htpasswd 

Require valid-user
Satisfy    any
Order      deny,allow
Deny from all
Allow from env=DEV

该解决方案足够灵活,允许访问多个开发环境,同时对任意数量的其他环境进行身份验证。在 git 提交之前无需忽略或编辑 htaccess。环境变量可能看起来有点矫枉过正,但它允许使用正则表达式,也可以在其他地方使用。

见:http ://httpd.apache.org/docs/2.2/howto/access.html

于 2014-04-01T20:34:54.680 回答
2

Debian/Ubuntu 的解决方案:

一方面/etc/apache2/envars必须改变:

## If you would like to pass arguments to the web server, add them below
## to the APACHE_ARGUMENTS environment.
#export APACHE_ARGUMENTS=''

## If you would like to pass arguments to the web server, add them below
## to the APACHE_ARGUMENTS environment.
export APACHE_ARGUMENTS='-D __DEV__'

现在可以使用

<IfDefine !__DEV__>
    ...
</IfDefine>
于 2014-04-25T20:14:17.040 回答
1

我确实喜欢回答问题,但是快速的谷歌搜索给了我你的答案。查看 apache 文档: http ://httpd.apache.org/docs/2.0/mod/core.html#ifdefine

IfDefine指令只能测试“parameter-name”,“parameter-name”是httpd在启动时设置的变量。

另请查看此站点,并向下滚动到表格: http ://turboflash.wordpress.com/2010/05/27/apache-environment-variables-visibility-with-setenv-setenvif-and-rewriterule-directives/

如果您像这样启动您的开发网络服务器,您的要求仍然是可能的:

$ httpd -DDEV

这将定义变量DEV。请注意,您不需要将其设置为任何内容,被定义基本上是将其设置为 1/true。如果它不存在,就像被设置为 false/0/null/etc...

于 2012-06-27T05:53:24.277 回答
1

我已经使用基于AccessFileName指令的不同方法解决了这个问题。

在我的 MAMP 环境中,我在<VirtualHost>配置中添加了以下内容:

AccessFileName .htaccess_dev

然后,我扫描了应用程序目录中的.htaccess文件并创建了与版本对应的符号链接,.htaccess_dev以便为所有这些文件提供相同的版本,并使应用程序可以在我的开发环境中运行。

然后,我找到了.htaccess包含文件路径的唯一文件.htpasswd并删除了符号链接并创建了它的修改副本。

我在.htaccess文件中有这个:

## production

AuthType Basic
AuthName "Admin"
AuthUserFile /srv/users/prod/apps/appname/public/sys-admin/.htpasswd
require valid-user

而这在.htaccess_dev

## development

AuthType Basic
AuthName "Admin"
AuthUserFile /Users/fregini/Work/MAMP/appname/sys-admin/.htpasswd 
require valid-user
于 2019-04-18T08:51:58.943 回答