Назад | Перейти на главную страницу

Сделайте обработку правил mod_rewrite до того, как fcgi увидит запрос

Есть ли способ иметь правила mod_rewrite в моем .htaccess файл вступит в силу до того, как PHP за fcgi увидит запрос?

У меня есть ссылка для подтверждения адреса электронной почты, которую я хочу перенаправить с root на страницу входа, прежде чем 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. Вы делаете запрос /?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 никому. Внутри <Directory> блок они будут работать как есть. В любом другом месте им потребуется дополнительная косая черта в начале.