web-dev-qa-db-fra.com

Forcer https entraîne la redirection de tous les dossiers

J'ai un site assez volumineux composé de pages Web régulières à la racine et de nombreux sites Joomla dans des dossiers.

Donc ça ressemble un peu à ça:

- index.php (root)
- about.php (root)
- product.php (root)
/joomlasite1
/joomlasite2
/joomlasite3

J'ai demandé à mon hébergeur d'aider à mettre une redirection dans le .htaccess pour forcer https et www. Mais quand ils ont fait cela, chaque site Joomla a été redirigé vers la racine et j'ai donc dû le supprimer.

C'est la règle qu'ils ont mise en place:

RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

Quelqu'un peut-il suggérer le meilleur moyen de le faire? Est-ce que je vais devoir mettre une redirection à la racine et également dans chaque dossier du site Joomla?

1
caffeinehigh

Ce que vous décrivez ressemble simplement à une redirection HTTP vers HTTPS (et non-www vers www) standard. Il est donc difficile de comprendre pourquoi les directives de l'hébergeur Web ont échoué de la façon que vous proposez.

Cependant, puisque vous vous attendriez à ce que chaque /joomlasite ait son propre fichier .htaccess qui contient également les directives mod_rewrite, cela risque de compliquer les choses. Même s’il est probable que ces sous-répertoires ne soient pas redirigés du tout. (Voir ci-dessous.)

Pour rediriger HTTP vers HTTPS et les non-www vers www, essayez ce qui suit dans la partie supérieure du fichier .htaccess à la racine de votre site:

RewriteEngine On

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_Host} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]

Assurez-vous d'effacer le cache de votre navigateur avant de tester.

Cela suppose également que le certificat SSL est installé sur votre serveur et que vous n'utilisez pas de proxy frontal SSL pour gérer votre SSL.

Notez qu'il s'agit d'une redirection temporaire 302. Ne le changez en une redirection permanente 301 que lorsque vous êtes sûr que tout fonctionne correctement. Les navigateurs 301 sont fortement mis en cache par le navigateur, ce qui peut rendre les tests difficiles.


PDATE: Si vous vouliez une solution plus générique ne nécessitant pas de codage en dur du domaine, vous pouvez utiliser l'une des solutions suivantes:

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_Host} !^www\.
RewriteCond %{HTTP_Host} ^(?:www\.)?(.+)\.?$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=302,L]

Ceci est très similaire à ce qui précède, à l'exception d'une directive supplémentaire RewriteCond, nécessaire pour capturer l'apex du domaine à partir de l'en-tête Host.

Une solution générique n'est pas nécessairement la "meilleure solution". (Bien que cela puisse être le cas.) Dans le monde infini des configurations de serveur variables, coder en dur le nom de domaine devient souvent la solution la plus fiable.


Cependant, cela ne peut rien faire pour les sous-répertoires contenant leurs propres fichiers .htaccess (si ces fichiers contiennent également des directives mod_rewrite). Si tel est le cas, vous devrez soit répéter les directives ci-dessus dans le fichier .htaccess de chaque sous-répertoire, soit activer l'activation de mod_rewrite en plaçant la directive suivante dans le fichier .htaccess de chaque sous-répertoire:

RewriteOptions InheritBefore

Ou bien, sur Apache 2.4.8+, vous pouvez plutôt inclure la directive suivante dans le fichier racine .htaccess:

RewriteOptions InheritDownBefore

Toutefois, la réussite de l'héritage mod_rewrite sans modifier les directives existantes dépend des autres directives que vous avez dans le fichier parent .htaccess.

l'héritage mod_rewrite n'est pas trivial. Les directives sont littéralement copiées sur place. Donc, si vous avez des directives par répertoire qui dépendent du chemin de fichier relatif, celles-ci peuvent tomber en panne. (C’est principalement pour cette raison que j’ai utilisé REQUEST_URI dans la directive ci-dessus, plutôt que de capturer le chemin d’URL à partir du motif RewriteRule.) Ainsi, la solution la plus simple - sans en savoir plus sur votre système - peut être simplement copier les directives de redirection (ci-dessus) dans chaque fichier sub .htaccess.


PDATE:

C'est la règle qu'ils ont mise en place:

RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

Si ces directives étaient utilisées dans le fichier .htaccess à la racine du document de votre site et que l'héritage mod_rewrite était également activé (comme décrit ci-dessus), cela présenterait le comportement que vous observiez, à savoir. tout dans /joomlasite est redirigé vers la racine. par exemple. http://www.example.com/joomlasite/foo serait redirigé vers https://www.example.com/foo à la racine - le répertoire /joomlasite est effectivement "perdu".

En effet, les directives héritées sont copiées sur place (comme indiqué ci-dessus). Si ces directives sont exécutées dans le contexte du fichier .htaccess du sous-répertoire /joomlasite, le chemin d’URL capturé par le modèle RewriteRule (et utilisé plus tard dans le $1 référence arrière) serait foo, pas joomlasite/foo, car le préfixe de répertoire (d'où est le fichier .htaccess situé) est d'abord retiré du chemin URL. Il en résulte une substitution de la forme https://www.example.com/foo.

Cependant, les directives que j'ai publiées précédemment, qui utilisent REQUEST_URI au lieu de $1, contournent ce problème car REQUEST_URI contient toujours le chemin d'accès complet à la requête.

2
MrWhite

Merci pour l'explication approfondie @MrWhite. J'ai une question. Quand j'ai essayé d'implémenter votre code, j'ai eu une boucle de redirection infinie. J'ai examiné des alternatives et celle ci-dessous a fonctionné. Juste curieux de savoir pourquoi les deux diffèrent? Existe-t-il une sorte de configuration de serveur qui en serait la cause?

RewriteEngine On


# Redirect HTTP with www to HTTPS with www
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_Host} ^www\. [NC]
RewriteRule .* https://%{HTTP_Host}%{REQUEST_URI} [R=302,L]
# Redirect HTTP without www to HTTPS with www
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_Host} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_Host}%{REQUEST_URI} [R=302,L]
# Redirect HTTPS without www to HTTPS with www
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_Host} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_Host}%{REQUEST_URI} [R=302,L]
0
caffeinehigh