.htaccess para reescrever URL E forçar https

.htaccess para reescrever URL E forçar https

site: exemplo.com

Subdiretório Joomla: example.com/joomla

Quero que a instalação do Joomla em example.com/joomla seja (ou pareça ser) a raiz do site, ou seja, as pessoas que visitam example.com são redirecionadas para example.com/joompla/index.php, mas ainda veem example.com na barra de URL.Também quero aproveitar esta oportunidade para forçar todas as conexões de entrada a usar HTTPS. Consegui fazer um ou outro usando scripts que encontrei online, mas não ambos com consistência.

Aqui está o que tenho até agora para .htaccess:

RewriteEngine on
RewriteBase /

# Rewrites all URLS without joomla in them
RewriteCond %{REQUEST_URI} !^/joomla/

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

# Rewrite all those to insert /joomla
RewriteRule ^(.*)$ /joomla/$1 [L]

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

Isso parece funcionar algumas vezes no Chrome, redirecionando para a instalação do Joomla e mudando para https, mas às vezes preciso forçar uma recarga forçada repetidamente para chegar lá. NUNCA funciona no Firefox, permanecendo em http nas raras ocasiões em que carrega o site.

Sou muito novo no .htaccess e não tenho certeza se desenvolvi a solução mais elegante ou abrangente para o problema acima. Já vi outros exemplos on-line usando RewriteCond %{HTTPS} !=onou RewriteCond %{SERVER_PORT} 80em conjunto com vários RewriteRulecomandos, mas não tenho certeza de como combinar esses comandos com as condições de reescrita de URL existentes e, como resultado, tenho certeza de que estou perdendo os cenários marginais.

Alguém com mais experiência pode me orientar nisso? Seria muito apreciado. Há alguns dias venho tentando variações de scripts encontrados on-line, mas ainda não encontrei as palavras mágicas.

Responder1

Algumas notas sobre suas diretivas existentes:

Reescrever Base /

Embora você tenha definido o RewriteBase, ele não está sendo usado em nenhuma de suas diretivas. O RewriteBasesó se aplica ao caminho relativosubstituições(você usou explicitamente um caminho de URL relativo à raiz nas diretivas relevantes).

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

Vocêprecisarverificar o nome do host solicitado? A menos que você esteja hospedando vários domínios (ou subdomínios) aos quais não deseja aplicar esta regra, então estedoençaé supérfluo.

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Essenuncaaciona um "redirecionamento", então não tenho certeza do que você está vendo no tráfego de rede.

(Na verdade, não há nada no código que você postou que acionaria um "redirecionamento" de HTTP para HTTPS.)

Este cabeçalho de resposta HTTP faz com que o navegador "atualize" automaticamente quaisquer solicitações derecursos vinculados(CSS, JS, imagens, recursos externos, etc.) da resposta inicial HTML (página) que de outra forma seria via HTTP (por exemplo, porque o URL real contém http://...) para ser via HTTPS. Nenhum "redirecionamento" real ocorre. E nada acontece com a resposta HTML inicial que possa ter sido via HTTP simples.

Este cabeçalho não é estritamente necessário se você implementou um redirecionamento HTTP para HTTPS em todo o site e todos os seus recursos vinculados já são HTTPS ou usam um URL relativo à raiz (ou relativo ao protocolo). Mas fornece uma boa rede de segurança. Observe, entretanto, que quaisquer recursos vinculados que não suportem HTTPS serão simplesmente quebrados - sem aviso do navegador ao usuário. Sem esse cabeçalho, o usuário potencialmente receberá um aviso de "conteúdo misto" do navegador (e o recurso vinculado falhará).

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

A RewriteConddiretiva (usada para evitar um loop de redirecionamento em "condições normais") corresponde joomla/a qualquer lugar no URL solicitado, até mesmo na string de consulta - o que é incorreto e pode resultar em redirecionamentos incorretos se joomla/aparecer em outro lugar no caminho do URL ou mesmo a string de consulta. Por exemplo, isso resultaria em um loop de redirecionamento se eu simplesmente acrescentasse ?joomla/ao final de qualquer URL.

Este "redirecionamento" deve irantesas reescritas internas. Em geral, os "redirecionamentos" devem vir antes das "reescritas" para evitar o redirecionamento de um URL reescrito e a exposição do URL reescrito aos seus usuários.

Conforme observado nos comentários, esse redirecionamento é para HTTP - o oposto do que você está tentando fazer (e resultará em uma pequena cadeia de redirecionamento ao implementar um redirecionamento de HTTP para HTTPS).

Algumas suposições:

  • O certificado SSL é instalado diretamente no servidor de aplicação, ou seja. sem Cloudflare (SSL flexível) ou outro proxy front-end que gerencie o SSL.
  • Você não está usando nenhum outro subdomínio. Apenas www.
  • O nome do host canônico não é www, ou seja. example.com(do redirecionamento na sua pergunta).
  • Você não está implementando HSTS no momento, então pode redirecionar para HTTPS e o nome do host canônico (ou seja, example.com) em um único redirecionamento.
  • O próprio Joomla já foi configurado para omitir o /joomlasubdiretório das URLs. /joomlanão está presente em nenhum link interno, incluindo links para recursos estáticos (CSS, JS, imagens, etc.)
  • Você não está exibindo nenhum arquivo da raiz do documento.Tudoé ir para o /joomlasubdiretório.

Cenário #1 – Um único .htaccessarquivo na raiz do documento.

(Conforme declarado nos comentários.)

Neste cenário, não há .htaccessarquivo "Joomla" no subdiretório de instalação ( /joomla) no qual rotear suas URLs para o front-controller do Joomla (ou seja, index.php). Nesse caso, index.phpdeve estar presente na URL e você não pode usar URLs "SEF" do Joomla.

O /.htaccessarquivo raiz ficaria mais ou menos assim:

RewriteEngine on

RewriteBase /joomla

# If a request tries to access /joomla directly, redirect it to its secured canonical 
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/joomla
RewriteRule ^joomla(?:$|/(.*)) https://example.com/$1 [R=302,L]

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Observe que usei redirecionamentos 302 (temporários) aqui para fins de teste. Sempre teste primeiro com redirecionamentos 302 e só mude para 301 (permanente) quando for confirmado que funciona bem. Os 301s são persistentemente armazenados em cache pelo navegador, o que pode tornar os testes problemáticos.

A REDIRECT_STATUSvariável de ambiente é usada para garantir que reescreveremos apenas solicitações diretas e não reescritas, da mesma forma que THE_REQUESTé usada na primeira regra. REDIRECT_STATUSestá vazio na solicitação inicial e definido como "200" (como no status de resposta HTTP 200 OK) após a primeira reescrita bem-sucedida. A diretiva RewriteRule (.*) $1 [L]pode parecer um pouco estranha à primeira vista (parece que ela se reescreve), no entanto, the RewriteBaseé prefixada à substituição resultante, portanto, na verdade, ela é reescrita para /joomla/<url>.

Cenário #2 – Dois .htaccessarquivos: raiz do documento e subdiretório

O .htaccessarquivo no /joomlasubdiretório seria o .htaccessarquivo razoavelmente padrão que vem com o Joomla. Isso roteia todas as solicitações para o front-controller do Joomla (ou seja, index.php) e permite o uso de URLs "SEF" do Joomla (ou seja, você não precisa incluir explicitamente index.phpno URL).

O /.htaccessarquivo raiz ficaria mais ou menos assim:

RewriteEngine on

RewriteBase /joomla

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Observe que o redirecionamento para remover o /joomlasubdiretório do URL foi removido e precisa ser inserido no /joomla/.htaccessarquivo. (Seria totalmente supérfluo se deixado aqui.)

Você não precisa da verificação em relação ao REDIRECT_STATUSenv var desta vez, pois o /joomla/.htaccesstestamentopegara solicitação após ela ter sido reescrita. (Assumindo que a herança mod_rewrite não foi habilitada.)

A Headerdiretiva pode ser movida para /joomla/.htaccessse você quiser - isso é opcional, pois será "herdado" de qualquer maneira.

Então, o /joomla/.htaccessarquivo conteria algo como o seguinte:

# JOOMLA: Set Options here

RewriteEngine on

# If a request tries to access here directly then redirect back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) https://example.com/$1 [R=302,L]

# JOOMLA: Rewrite rules to block out some common exploits.
# :

# Leave the RewriteBase directive commented out - it's not required
#RewriteBase /joomla

## Begin - Joomla! core SEF Section.
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
## End - Joomla! core SEF Section.

O /joomla/.htaccessarquivo é vagamente baseado emo código no site Joomla, no entanto, omiti os elementos/comentários comuns e alterei a "Seção SEF" para ser relevante para o subdiretório. (O Joomla também usa um regex menos eficiente .*em vez de simplesmente ^.)

informação relacionada