web-dev-qa-db-ja.com

.htaccessとmod_rewriteを使ってSSL / httpsを強制する

どのように私はPHPで特定の.htaccessとmod_rewriteページを使ってSSL/httpsに強制することができます。

216
Sanjay Shah

Apacheの場合、 mod_ssl を使用して、 SSLRequireSSL Directive でSSLを強制することができます。

このディレクティブは、現在の接続でHTTP over SSL(すなわちHTTPS)が有効になっていない限り、アクセスを禁止します。これは、SSL対応の仮想ホストやディレクトリ内で、保護すべきものを露呈する設定エラーから守るために非常に便利です。このディレクティブが存在すると、SSLを使用していないすべての要求が拒否されます。

しかしこれはhttpsへのリダイレクトをしません。リダイレクトするには、.htaccessファイルで mod_rewrite を指定して次の操作を試してください。

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

またはで与えられたさまざまなアプローチのいずれか

プロバイダが.htaccessを無効にしている場合は、これをPHP内から解決することもできます(ただし、要求されてからは不可能です)。

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();
    }
}
413
Gordon

私はmod_rewriteソリューションをプロキシサーバーと未プロキシサーバーの両方でうまく動作することを見つけました。

通常のHTTPSリダイレクトでCloudFlare、AWS Elastic Load Balancing、Heroku、OpenShiftまたはその他のCloud/PaaSソリューションを使用していてリダイレクトループを使用している場合は、次のコードを試してください。代わりに。

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]
48
raphinesse

PHPソリューション

Gordonの非常に包括的な答えから直接借りて、あなたの質問はHTTPS/SSL接続を強制することにおいてページ特有であると述べていることに注意してください。

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>' );
    }
  }
}

それから、PHP経由で強制的に接続したいこれらのページの一番上に近いところで、(そして他の)カスタム関数を含む一元管理されたファイルをrequire()し、それから単にforceHTTPS()関数を実行します。

HTACCESS/mod_rewriteソリューション

私はこの種の解決策を個人的には実装していません(私は上記のようにPHP解決策を使う傾向がありましたが、単純にするため)。

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]
35
Luke Stevenson

書き換えベースのソリューション:

Htaccessで次のコードを使用すると、すべてのhttp要求が自動的にhttpsに転送されます。

RewriteEngine on

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

これは、www以外およびwww httpリクエストをwwwバージョンのhttpsにリダイレクトします。

別の解決策(Apache 2.4 *)

RewriteEngine on

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

2.4以降、%{REQUEST_SCHEME}変数がmod-rewriteに追加されたため、これは下位バージョンのApacheでは機能しません。

9
starkeen

私はApacheがディレクトリ深さを越えて複数の.htaccessファイルを使用する場合--- 最悪の継承規則を持っていることを指摘したいと思います。 2つの重要な落とし穴:

  • 最も深い.htaccessファイルに含まれている規則だけがデフォルトで実行されます。これを変更するにはRewriteOptions InheritDownBeforeディレクティブ(または類似のもの)を指定しなければなりません。 (質問を参照)
  • パターンは、指定された規則を持つ.htaccessファイルを含む上位ディレクトリではなく、サブディレクトリを基準としたファイルパスに適用されます。 (説明を参照)

つまり、サブディレクトリで他の.htaccessファイルを使用している場合、 Apache Wiki で提案されているグローバルソリューションはnot動作します。私は修正版を書きました。

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/
7
lpd

このコードは私のために働きます

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

シンプルで簡単、以下を追加するだけ

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

他の答えのどれも私のために働いた。私のセットアップは、AWS Beanstalk上のPHPアプリであり、従来のELBです。 .htaccessアプローチは機能しないため、リダイレクトルールをApache httpd.confファイルに適用する必要がありました。例えば。 (AWSドキュメントから):

Apacheサーバー:仮想ホストファイル方式(推奨)

  1. Apache構成ファイルを開きます。可能な場所には、/ etc/httpd/conf/httpd.conf(Apache 2/httpd)、/ etc/Apache2/sites-enabled /(Apache 2.4)、または/etc/Apache2/Apache2.conf(Apache on Ubuntu)が含まれます。

  2. 次のような構成ファイルのVirtualHostセクションに書き換えルールを追加します。

    RewriteEngine On RewriteCond%{HTTP:X-Forwarded-Proto} = http RewriteRule。* https://% {HTTP:Host}%{REQUEST_URI} [L、R = permanent]

  3. Apache構成ファイルを保存します

  4. Apacheを再起動します

こちらをご覧ください: https://www.youtube.com/watch?v=hvqZV_50GlQ

https://aws.Amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/

0
Risteard