web-dev-qa-db-fra.com

RewriteRule Le dernier indicateur [L] ne fonctionne pas?

php_flag display_errors 1
php_value auto_prepend_file init.php
RewriteEngine on 
RewriteRule ^$  /id/authenticate [R]
RewriteRule ^login_openid$  /id/login_openid.php [QSA,L]
RewriteRule ^authenticate$  /id/authenticate.php [QSA,L]
RewriteRule ^facebook$  /id/facebook.php [QSA,L]
RewriteRule ^createfromopenid$  /id/createfromopenid.php [QSA,L]

RewriteRule .* - [L,R=403]

Ceci est mon fichier .htaccess. Dans le serverconfig j'ai juste AllowOVerride all.

Si je demande l'URL http://mydomain.com/id/authenticate J'obtiens une erreur 403. Si je supprime la dernière règle, cela fonctionne. Ne devrait pas le [L] plat empêcher d'autres règles de se produire?

Éditer:

Mon fichier htaccess est dans le sous-dossier "id", donc les règles fonctionnent.

29
The Surrican

La règle [L] Fonctionne bien - vous ne savez tout simplement pas comment cela fonctionne .

Quand Apache voit le drapeau [L] Et les correspondances de règles (la réécriture se produit), Apache ira à la prochaine itération et commencera à faire correspondre toutes les règles à partir du haut. Le drapeau [L] Signifie "ne pas traiter les règles ci-dessous dans cette itération ".

Oui, le documentation Apache n'est pas clair à 100% à ce sujet (ce qui signifie qu'il peut être amélioré), mais fournit suffisamment d'informations pour le comprendre finalement.


Apache arrêtera le cycle de réécriture dans quelques situations:

  1. Aucune règle correspondante (aucune réécriture n'a eu lieu);

  2. Correspondance de la règle "quitter maintenant" (par exemple RewriteRule .* - [L]);

  3. La réécriture se produit, mais l'URL d'entrée et les URL finales sont les mêmes (se produit aux 2e-3e itérations lorsque la règle "mal" écrite réécrit la même URL dans la même URL.

    Par exemple RewriteRule (.*) /index.php?page=$1 [L]:

    • /hello => /index.php?page=hello
    • à la prochaine itération, il réécrira /index.php => /index.php?page=index.php
    • et à la 3ème itération ce sera /index.php => /index.php?page=index.php .. ce qui n'a plus de sens maintenant);
  4. La limite d'itération de réécriture est atteinte (par défaut = 10) - c'est si vous avez entré un cycle de réécriture infini (la valeur est contrôlée par Directive LimitInternalRecursion ).


Avec toutes les informations susmentionnées, je peux dire que vos règles actuelles fonctionnent comme prévu . Cela signifie que vous devez changer la logique et vous débarrasser de la dernière règle (peut-être gérer ce moment dans le parent .htaccess .. ou le gérer différemment - tout dépend de la façon dont votre application est construite, je ne veux pas faire de suppositions sauvages ).

75
LazyOne

Mettez ceci devant votre cath all règle.

RewriteCond %{ENV:REDIRECT_STATUS} !=200

Le problème est qu'une fois que le drapeau [L] est traité, tous les RewriteRules suivants sont en effet ignorés, cependant, le fichier est à nouveau traité depuis le début, maintenant avec la nouvelle URL.

Cette condition magique ne traitera pas le catch all si le fichier a déjà été redirigé.

PS: Si cela ne fonctionne pas, vous devrez peut-être modifier légèrement la condition: 200, !=200, ^., ^$.
Apparemment, la variable est réglée sur 200 pour une redirection, mais aussi d'autres pages (erreur et autres) définissez-la sur une certaine valeur. Maintenant, cela signifie que vous vérifiez si elle is empty, is not empty, is 200 ou is not 200, selon vos besoins.

9
Qwerty