首页 文章

使用.htaccess和mod_rewrite强制SSL / https

提问于
浏览
208

如何使用PHP中特定的.htaccess和mod_rewrite页面强制使用SSL / https .

10 回答

  • 7

    对于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]
    

    或者给出的任何一种方法

    您也可以在PHP中解决此问题,以防您的提供商禁用.htaccess(这是不可能的,因为您要求它,但无论如何)

    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();
        }
    }
    
  • 397

    基于Mod-rewrite的解决方案:

    在htaccess中使用以下代码会自动将所有http请求转发到https .

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

    这会将您的 non-wwwwww http请求重定向到https的 www 版本 .

    另一个解决方案(Apache 2.4 *)

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

    这不适用于较低版本的apache,因为%变量已从2.4添加到mod-rewrite .

  • 0

    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]
    
  • 34

    我只想指出,当跨目录深度使用多个.htaccess文件时,Apache的继承规则最差 . 两个关键陷阱:

    • 默认情况下,只会执行最深的.htaccess文件中包含的规则 . 您必须指定 RewriteOptions InheritDownBefore 指令(或类似指令)才能更改此指令 . (see question)

    • 模式应用于相对于子目录的文件路径,而不是包含具有给定规则的.htaccess文件的上层目录 . (see discussion)

    这意味着如果在子目录中使用任何其他.htaccess文件,则Apache Wiki上建议的全局解决方案不起作用 . 我写了一个修改后的版本:

    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/
    
  • 43

    我找到了一个适用于代理服务器和未代理服务器的 mod_rewrite 解决方案 .

    如果您正在使用CloudFlare,AWS Elastic Load Balancing,Heroku,OpenShift或任何其他Cloud / PaaS解决方案,并且您遇到具有正常HTTPS重定向的重定向循环,请尝试使用以下代码段 .

    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]
    
  • 8

    简单的一个:

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

    用example.com替换你的网址

  • -1

    只需使用Apache .htaccess强制SSL即可

    SSLOptions +StrictRequire
    SSLRequireSSL
    

    重定向上面的答案是正确的

  • 0

    试试这个代码,它适用于所有版本的URL

    RewriteCond %{HTTPS} off
    RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
    RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]
    
  • -1

    这段代码适合我

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

    简单易用,只需添加以下内容即可

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

相关问题