在 fcgi 看到请求之前使 mod_rewrite 规则进程

在 fcgi 看到请求之前使 mod_rewrite 规则进程

有没有办法让我.htaccess文件中的 mod_rewrite 规则在 fcgi 后面的 PHP 看到请求之前生效?

我有一个电子邮件验证链接,我想在 PHP 在数据库中将其标记为已确认之前将其从根目录重定向到登录页面。

这些是我在我的 中的规则.htaccess,它们起作用,但是 PHP 在重写规则生效之前看到了请求。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{QUERY_STRING} activation_key=
    RewriteRule ^$ /login [R,L]
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

当 PHP 看到包含查询字符串的请求时activation_key,它会将用户标记为已激活。如果用户已激活,页面将显示“未知验证链接”错误。

通过这些重写规则,请求会重定向到页面/login并显示错误,这表明 - 我认为 - PHP 已经看到了该请求。

这是 mod_fastcgi 配置:

<IfModule mod_fastcgi.c>
    DirectoryIndex index.html index.shtml index.cgi index.php
    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
</IfModule>

答案1

如果我理解正确的话:

  1. 您向 发出请求/?activation_key=foobar,Apache 返回响应以将您重定向到/login
  2. 您向 发出后续请求/login,该页面显示它已经看到了验证链接。但此请求中没有activation_key,它只存在于第一个请求中。它可能之前已经看到过空字符串,这就是它现在抛出错误的原因。(您的 PHP 脚本中的确切逻辑可能与此解释不符,但我怀疑它是类似的。)

尝试像这样更改重写规则:

RewriteCond %{QUERY_STRING} activation_key=[^&]*
RewriteRule ^$ /login?activation_key=%1 [R,L]

它将捕获激活密钥并在下次请求时将其传递,/login以便 PHP 获得该密钥。

在调试时回显或记录查询字符串或整个请求甚至整个$_SERVER超级全局变量到文件可能是值得的。


您的上一条重写规则/中有一个多余的内容,但其实并不需要。以下规则会更好:

RewriteRule ^ index.php [L]

.htaccess文件和相关AllowOverride all指令会带来性能损失。在使用strace和观察所有文件操作以寻找.htaccess文件可能隐藏的所有位置时,这一点变得非常明显。如果您运行的是自己的 Apache 服务器而不是共享主机,那么您可能还想将这些规则放入主配置中并设置AllowOverride为 none。在<Directory>块内,它们将按原样工作。在其他地方,它们将需要一个额外的前导斜杠。

相关内容