redirecionamento htaccess para https: // www

309

Eu tenho o seguinte código htaccess:

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteCond !{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>

Quero que meu site seja redirecionado para https://www.HTTPS e imponha o www.subdomínio, mas quando eu acesso http://www.(sem HTTPS), ele não me redireciona para https://wwwHTTPS.

bigben
fonte
Deveria serRewriteCond %{HTTPS} =off
Michael Berkowski
1
Se eu fizer isso, ele redireciona para https: / / ww ww w w.
bigben
Caro @bigben, você aceitou uma resposta errada aqui! você pode descobrir por que está errado na minha resposta .
Amir Fo

Respostas:

632

Para forçar o HTTPS pela primeira vez, você deve verificar a variável de ambiente correta %{HTTPS} off, mas sua regra acima precede a opção www.Como você tem uma segunda regra a ser aplicada www., não a use na primeira regra.

RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Sobre proxy

Quando está por trás de algumas formas de proxy, nas quais o cliente está se conectando via HTTPS a um proxy, balanceador de carga, aplicativo de passageiro etc., a %{HTTPS}variável pode nunca estar one causar um loop de reescrita. Isso ocorre porque seu aplicativo está realmente recebendo tráfego HTTP simples, mesmo que o cliente e o proxy / balanceador de carga estejam usando HTTPS. Nesses casos, verifique o X-Forwarded-Protocabeçalho em vez da %{HTTPS}variável. Esta resposta mostra o processo apropriado

Michael Berkowski
fonte
14
Em alguns casos, seu certificado pode ser bom apenas para um único domínio (pode funcionar com www, mas não sem, por exemplo). Nesses casos, redirecione primeiro para o domínio correto e depois para https, caso contrário, você receberá uma mensagem de erro no seu navegador.
Nick Benson
19
Quando eu usei RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]um URL como exaple.com/?bla=%20 tornou-se exaple.com/?bla=%2520 , ou seja, o sinal de porcentagem foi codificado. Considere usar o sinalizador NEpara evitar a codificação dupla:RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
Bata
5
isso me dá um loop de redirecionamento em um servidor, funciona em outro. Eu realmente não sei por que
#
4
@ user151496 O servidor com falha usa algum tipo de proxy HTTP, como passar por um cache do Varnish ou no Passenger? Nesse caso, talvez seja necessário verificar o X-Forwarded-Protocabeçalho para verificar o HTTPS em vez da %{HTTPS}variável. Você não disse qual parte causa o loop, a wwwparte HTTPS, mas essa é a primeira coisa que me vem à mente.
Michael Berkowski
5
Estritamente falando, as duas regras que você tem acima estão na ordem errada. Se uma solicitação for solicitada http://example.com( por exemplo, HTTP e não www), você receberá um redirecionamento duplo. Primeiro para https://example.com(a primeira regra) e depois para https://www.example.com(a segunda regra). Você pode corrigir isso simplesmente revertendo essas duas regras, pois as duas regras redirecionam para HTTPS independentemente.
MrWhite
148

A resposta de Michals funcionou para mim, embora com uma pequena modificação:

Problema:

quando você possui um único certificado de segurança do site , um navegador que tenta acessar sua página sem https: // www. (ou qualquer domínio que o seu certificado cubra) exibirá uma tela de aviso vermelha feia antes mesmo de receber o redirecionamento para a página https segura e correta.

Solução

Primeiro use o redirecionamento para o www (ou qualquer domínio coberto pelo seu certificado) e somente então o redirecionamento https. Isso garantirá que seus usuários não sejam confrontados com nenhum erro porque seu navegador vê um certificado que não cobre o URL atual.

#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Larzan
fonte
5
+1 porque é a melhor opção para esse cenário, mas observe que isso não impedirá que o mesmo problema aconteça se o cliente acessar https://example.com, mas, na minha opinião, esse é o formato menos provável de ser digitado por um usuário. (A resposta aceita também terá o mesmo problema)
Joshua Goossen
@ Larzan: Isso está errado. A exceção de certificação ocorre apenas porque você faz 2 redirecionamentos reais . Substitua "[L, R = 301]" por "[R = 301]". As regras não são abortadas. L = LAST
defim
Se você precisar manipular https://sem wwwter um certificado apenas no www, basta adicionar esta regra à solução: RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{HTTPS} on RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI}[L,R=301] Ela simplesmente volta ao httptentar se conectar https://example.compara evitar erros de certificado.
Eric Burel
1
As duas regras deve ser revertida qualquer maneira (como você fez), a fim de evitar um duplo redirecionamento ao solicitar http://example.com(ou seja, HTTP e sem www.)
MrWhite
@EricBurel Você não pode evitar o erro de certificado nesta instância - o handshake SSL ocorre antes da execução do seu código (que é o ponto principal do SSL em primeiro lugar). Se o seu redirecionamento pudesse ser executado antes do erro de certificação do navegador, isso implicaria que a solicitação já havia sido feita por uma conexão insegura - o que seria uma falha fundamental no modelo SSL.
precisa saber é o seguinte
99

Se você estiver usando o CloudFlare ou um CDN semelhante, receberá um erro de loop infinito com as soluções% {HTTPS} fornecidas aqui. Se você é um usuário do CloudFlare, precisará usar o seguinte:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Andrew
fonte
2
Observe que o conselho atual no site de suporte do Cloudflare é um pouco diferente: support.cloudflare.com/hc/en-us/articles/…
ColinMcDermott 22/14
1
Concordo com @ h0mayun, o conselho que o Cloudflare fornece resultados em um loop de redirecionamento, enquanto esse código aqui funciona perfeitamente - obrigado!
hobailey
2
Eu corro angularjs no ec2. As soluções que usam RewriteCond% {HTTPS}! = On fornecem um redirecionamento infinito (não sei por que). Esta solução, com o X-Forwarded-Proto, parece funcionar. Obrigado!
Mark Watkins
3
Eu modifiquei =httppara !=httpspara nossos ambientes. X-Forwarded-Protocabeçalho não foi declarado se http, o mesmo !=httpsaconteceu com o truque.
Johnathan Elmore
Obrigado por esse insight! Passei horas tentando descobrir por que {HTTPS}não estava funcionando. Eu tentei {ENV:HTTPS}e até mesmo {SERVER_PORT} 443, mas no final foi porque eu precisava verificar os cabeçalhos de solicitação HTTP personalizados do Cloudflare.
camslice 17/04
56

MAU SOLUÇÃO E POR QUE!

Nunca use a solução abaixo porque, quando você estiver usando o código deles, é algo como:

RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301]

O navegador acessa:

http://example.com

Em seguida, redireciona para:

https://example.com

Em seguida, redireciona para:

https://www.example.com

Isso é muita solicitação para o servidor.

A maioria das respostas até aceitas tem esse problema.


MELHOR SOLUÇÃO E RESPOSTA

Este código tem uma [OR]condição para evitar alterações duplas no URL!

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]
Amir Fo
fonte
3
"MAU SOLUÇÃO E POR QUE!" - Essas regras estão na ordem errada. Inverta essas duas regras e estará correto - você receberá apenas um redirecionamento e não dois.
MrWhite
4
Sim, o código fornecido resulta em 2 redirecionamentos - não estou contestando isso - tudo o que estou dizendo é que você simplesmente precisa reverter essas regras para resolver esse problema; nenhuma outra alteração é necessária. (A resposta "aceite" é realmente incorreta - que parece ser o que você está se referindo -. As directivas estão na ordem errada)
MrWhite
1
yup @AmirForsati está certo. está redirecionando duas vezes e essa deve ser a resposta aceita.
Zakir hussain
4
Você pode usá-lo se quiser manter a variável domainname:RewriteEngine On RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTPS} off RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I.devries
Isso está me redirecionando para wp-content/cache/page_enhanced/e assim por diante. Como posso consertar isso? Edit: Parece que eu preciso colocá-lo no topo .htaccess. Obrigado pelo script :)
Giacomo
35

Essa é a melhor maneira que encontrei para usuários proxy e não proxy

RewriteEngine On

### START WWW & HTTPS

# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

### END WWW & HTTPS
llioor
fonte
2
Correto Essa é a melhor maneira que eu encontrei para usuários proxy e não proxy +1
Deep 3015
1
Este é o melhor, como ele resolve múltiplas 301 redirecionamentos
Niraj Chauhan
1
melhor solução de sempre.
SM Jobayer Alam
1
Ótima resposta. Este é o único que funcionou para mim. Funciona se você estiver atrás do Cloudflare (embora eu não tenha regras de página configuradas no Cloudflare).
jasonco
A única solução que funciona em todos os meus casos. Mas e se eu quiser fazer o contrário e remover todos os "www".
FedeKrum
27

Existem muitas soluções por aí. Aqui está um link para o wiki do apache, que lida diretamente com esse problema.

http://wiki.apache.org/httpd/RewriteHTTPToHTTPS

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
Vynz
fonte
Descobri alterando a condição de reescrita de RewriteCond %{HTTPS} offpara RewriteCond %{HTTPS} !=onque o redirecionamento sempre acontecesse, essa parece a melhor resposta para mim.
Samuel Hawksby-Robinson
Esta solução deve ser aceita como uma resposta correta! Trabalhou para mim também!
AndrewShmig
11

Para redirecionar http: // ou https: // para https: // www, você pode usar a seguinte regra em todas as versões do apache:

RewriteEngine on

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Apache 2.4

RewriteEngine on

RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Observe que a variável% {REQUEST_SCHEME} está disponível para uso desde o apache 2.4 .

starkeen
fonte
1
Problema !: Se HTTP_HOST já contiver www. mas o esquema não é HTTPS, você acaba em www.www. no seu host.
Jpsy
@Jpsy você está certo. Eu atualizei o destino de redirecionamento. Obrigado pela sua contribuição.
starkeen
1
Isso é quase o que eu estava procurando, mas quero manter o domínio genérico, como em outros exemplos. É possível?
Cronograma7
8

Se você estiver no CloudFlare, use algo assim.

# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect

Isso salvará você do loop de redirecionamento e redirecionará seu site para SSL com segurança.

PS: É uma boa ideia verificar o mod_rewrite.c!

Ahmad Awais
fonte
ele não redireciona https: // theurlwithoutwww.com para https: // www.
thesearentthedroids
Na verdade, essa é apenas uma solução que funcione se você tiver algumas diretivas "adicionar www" anteriormente. Outras soluções me dão "muitos redirecionamentos".
Daniel.P.
3
RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
Анастасия Ермолик
fonte
2
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

Notas: Verifique se você executou as seguintes etapas

  1. reescrever sudo a2enmod
  2. serviço sudo reinício apache2
  3. Adicione o seguinte no seu arquivo vhost, localizado em /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
  Require all granted
</Directory>

Agora seu .htaccess funcionará e seu site será redirecionado para http: // para https: // www

Kundan roy
fonte
1

Semelhante à solução htaccess de Amir Forsati redirecionada para https: // www, mas para nome de domínio variável, sugiro:

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%2%{REQUEST_URI} [R=301,L]
Bernhard Bodenstorfer
fonte
0

Defina no seu arquivo .htaccess

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Adam Kozlowski
fonte
-2

Eu tento a primeira resposta e não funciona ... Este trabalho:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
Jackssn
fonte