.Htaccess ve mod_rewrite kullanarak SSL / https'yi zorla


Yanıtlar:


438

Apache mod_ssliçin SSL'yi aşağıdakilerle zorlamak için kullanabilirsiniz SSLRequireSSL Directive:

Bu yönerge, geçerli bağlantı için SSL üzerinden HTTP (HTTPS) etkinleştirilmedikçe erişimi yasaklar. Bu, SSL etkin sanal ana makinenin veya dizinlerin içinde, korunması gereken şeyleri ortaya çıkaran yapılandırma hatalarına karşı savunmak için çok kullanışlıdır. Bu direktif mevcut olduğunda SSL kullanmayan tüm istekler reddedilir.

Bu, https'ye bir yönlendirme yapmayacaktır. Yeniden yönlendirmek için, mod_rewrite.htaccess dosyanızda aşağıdakileri deneyin

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

veya verilen çeşitli yaklaşımlardan herhangi biri

Sağlayıcınızın .htaccess'i devre dışı bırakmış olması durumunda bunu PHP içinden de çözebilirsiniz (bu istemediğinizden beri olası değildir, ancak yine de)

if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
    if(!headers_sent()) {
        header("Status: 301 Moved Permanently");
        header(sprintf(
            'Location: https://%s%s',
            $_SERVER['HTTP_HOST'],
            $_SERVER['REQUEST_URI']
        ));
        exit();
    }
}

1
Durumumuzda bu harika çünkü şu anda http ve https trafiğinin bir karışımı var. Yönetici alanımız için sitenin geri kalan kısmını http.
Michael J.Calkins

1
Mod_rewrite yöntemini kullandığımda, https'ye gönderiliyor ancak "Sayfa düzgün bir şekilde yönlendirmiyor" hatasıyla.
Çek teknolojisi

11
Takip: Benzer bir sorun yaşıyorsanız, sunucunuzu ve HTTP değişkenlerinizi kontrol edin. Sunucunuz proxy kullanıyorsa, SSL'nin açık olup olmadığını kontrol etmek için %{HTTP:X-Forwarded-Proto}veya %{HTTP:X-Real-Port}değişkenleri kullanmak isteyebilirsiniz .
Çek teknolojisi

8
Eğer yaşarsanız yönlendirme döngüler proxy (arkasında çalışan sunucularda CloudFlare , Openshift ), bkz bu cevabı çözüm için o vaka için çalışmalar da.
raphinesse

4
@GTodorov - Alanı kaldırmak benim için yeniden yazmayı kırdı. Yeniden yazma bilgim (sınırlı) bilgimden sözdizimi RewriteRule <input-pattern> <output-url>. Bu nedenle, alanın orada olması gerekir ve single ^sadece "tüm giriş URL'leriyle eşleştir" der.
Sphinxxx

54

mod_rewriteProxy ve proxy olmayan sunucular için iyi çalışan bir çözüm buldum .

Eğer kullanıyorsanız CloudFlare, AWS Elastik Yükü Dengeleme, Heroku, OpenShift veya başka herhangi Bulut / PaaS çözümü ve karşılaştığınız yönlendirme döngüler normal HTTP yönlendirmeleri ile, yerine aşağıdaki pasajı deneyin.

RewriteEngine On

# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]

# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on

# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Bu harika teşekkürler! Ama belki de posta durumu eklemek gerekir? RewriteCond% {REQUEST_METHOD}! ^ POST $
Aleksej

@Aleksej Doğru, şifrelenmemiş POST isteklerini bozar. Ama bence bu iyi bir şey. Bu şekilde, insanlar yanlış bir şey yaptıklarını fark edeceklerdir. Sanırım en iyi şey, onları servisinizi nasıl doğru kullanacağınız konusunda bilgilendiren bir sayfaya yönlendirmek olacaktır.
18'de raphinesse

@raphinesse Bu sorunun cevabını biliyor musunuz: stackoverflow.com/questions/51951082/…
RRN

36

PHP Çözümü

Doğrudan Gordon'un çok kapsamlı cevabından ödünç alarak, sorunuzun HTTPS / SSL bağlantılarını zorlamada sayfaya özgü olduğunu belirtiyorum.

function forceHTTPS(){
  $httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  if( count( $_POST )>0 )
    die( 'Page should be accessed with HTTPS, but a POST Submission has been sent here. Adjust the form to point to '.$httpsURL );
  if( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']!=='on' ){
    if( !headers_sent() ){
      header( "Status: 301 Moved Permanently" );
      header( "Location: $httpsURL" );
      exit();
    }else{
      die( '<script type="javascript">document.location.href="'.$httpsURL.'";</script>' );
    }
  }
}

Daha sonra, PHP aracılığıyla bağlanmaya zorlamak istediğiniz bu sayfaların üst kısmına yakın olarak, require()bu (ve diğer) özel işlevleri içeren merkezi bir dosya oluşturabilir ve ardından forceHTTPS()işlevi çalıştırabilirsiniz .

HTACCESS / mod_rewrite Çözümü

Ben şahsen bu tür bir çözüm uygulamadı (basitlik için yukarıdaki gibi PHP çözümünü kullanma eğiliminde), ama aşağıdaki, en azından, iyi bir başlangıç ​​olabilir.

RewriteEngine on

# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$

# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

meraktan, neden RewriteCond %{REQUEST_METHOD} !^POST$?
Haziran'da depoulo

12
Çünkü POST parametreleri bir yönlendirmede tutulmaz. Tüm POST gönderimlerinin güvenli olduğundan emin olmak istiyorsanız bu satırı atlayabilirsiniz (güvenli olmayan POST gönderimleri yok sayılır).
Luke Stevenson

@Lucanos - POST olduğunda http veya https'ye yönlendirmeyi zorlamayan bir RewriteCond nasıl yazılır? .Htaccess, belirli belirli sayfalarda HTTPS'yi zorlar ve geri kalanında HTTP'yi zorlar. Ancak, HTTPS sayfalarında, web köküme gönderilen formlar var. Form, eylem URL'sini HTTPS olarak belirtir. Ancak, web kökü HTTPS'yi zorlamak için belirtilen sayfalardan biri olmadığından, .htaccess'im bir yönlendirmeyi zorlar - bu da POST değişkenlerinin kaybolduğu anlamına gelir. POST üzerindeki yönlendirmeleri nasıl önleyebilirim?
StackOverflowNewbie

1
@StackOverflowNewbie: Satır RewriteCond %{REQUEST_METHOD} !^POST$, POST gönderimlerinin bu yönlendirmelerden etkilenmesini önlemelidir.
Luke Stevenson

Bu PHP sürümünü beğendim. Bir POST'u dikkate aldığından ve başlıklar zaten gönderildiyse daha iyi işlediğinden çok daha iyidir.
TheStoryCoder

10

Mod-yeniden yazma tabanlı çözüm:

Aşağıdaki kodu htaccess içinde kullanmak tüm http isteklerini otomatik olarak https'ye iletir.

RewriteEngine on

RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

Bu, www olmayan ve www http isteklerinizi https'nin www sürümüne yönlendirir .

Başka bir çözüm (Apache 2.4 *)

RewriteEngine on

RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

2.4'ten beri mod-rewrite'a% {REQUEST_SCHEME} değişkeni eklendiğinden bu, apache'nin alt sürümlerinde çalışmaz.


9

Sadece dizin derinliklerinde birden çok .htaccess dosyası kullanırken Apache'nin en kötü kalıtım kurallarına sahip olduğunu belirtmek isterim . İki önemli tuzak:

  • Yalnızca en derin .htaccess dosyasında bulunan kurallar varsayılan olarak gerçekleştirilir. Bunu RewriteOptions InheritDownBeforedeğiştirmek için yönerge (veya benzeri) belirtmeniz gerekir . (soruya bakın)
  • Desen, verilen kurala sahip .htaccess dosyasını içeren üst dizine değil, alt dizine göre dosya yoluna uygulanır. (tartışmaya bakın)

Bu araçlar önerdi küresel çözüm Apache Wiki yok değil sen alt dizinleri başka .htaccess dosyalarını kullanıyorsanız çalışır. Ben değiştirilmiş bir sürümü yazdı:

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteOptions InheritDownBefore
# This prevents the rule from being overrided by .htaccess files in subdirectories.

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

RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,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/

0

Basit ve Kolay, sadece aşağıdakileri ekleyin

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

Bu hemen hemen tüm internette insanların https zorlamak için yapmaları gerektiğini söylüyor. Ancak, bunu her yaptığımda, tüm web sitem Yasaklandı veya görüntüleme izniniz yok. böyle bir şey ... Neyi yanlış yapıyorum? Bu konuda bir soru göndermeden önce herhangi bir fikriniz olup olmadığını bilmek istiyorum.
ThN

Benzer bir sorunum vardı ve kuralları https.conf dosyasına uygulamak zorunda kaldım. Cevabımı aşağıda görebilirsiniz.
Risteard

-1

Bu kod benim için çalışıyor

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

-1

Basit olan :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow

url'nizi example.com ile değiştirin


HAYIR! Site URL'sinin dinamik olması gerekir.
Amir Savand

-1

SSL'yi sadece Apache .htaccess ile zorlamak için kullanabilirsiniz

SSLOptions +StrictRequire
SSLRequireSSL

yönlendirme için yukarıdaki cevap doğrudur


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.