douzhun8615 2015-12-21 02:17
浏览 119
已采纳

如果连接是纯HTTP,则尝试了解用于重定向到HTTPS的不同方法

So I’ve seen a couple different methods on the internet but I’m not sure what the actual difference is between them or why one is better than the other.

  1. Rewrite rule
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
  1. Redirect rule
<VirtualHost *:80>
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost >

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost >
  1. Redirect PHP
if($_SERVER['HTTPS'] != "on") {
  $redirect = "https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
  header("Location:$redirect"); 
  exit();
} 

Currently I’m using #3, I put it in a seperate file and include it in any page that requires HTTPS.

Is this bad practice? Should I be using a different method to use HTTPS?

  • 写回答

3条回答 默认 最新

  • douzhu5900 2015-12-21 05:04
    关注

    Shorter answer.

    In general, this all falls under the “depends” rubric.

    But for the example you are showing, I would say simply placing Redirect "/" "https://www.example.com/" in an .htaccess file on the plain-HTTP site is the best method. Just note that if you are dealing with specific pages—and I have no clue what your site layout looks like—then the entries in that .htaccess file might look something like this:

    Redirect "/login.php" "https://www.example.com/login.php"
    Redirect "/account.php" "https://www.example.com/account.php"
    Redirect "/starwars_spoilers.php" "https://www.example.com/starwars_spoilers.php"
    

    Longer answer.

    You ask this:

    So I’ve seen a couple different methods on the internet but I’m not sure what the actual difference is between them or why one is better than the other.

    In my humble opinion, I see all of these methods as valid but each has it’s own quirks and idiosyncrasies based on usage and system needs. Based on what you are describing I would recommend using either method number 1 or 2 in an .htaccess file and just placing it in the server codebase that requires forcing HTTPS connections. But I would only use the PHP method if you have larger coding needs past simple “Is it HTTPS or not?” logic.

    Here is my breakdown.

    1. Rewrite rule: The Apache server mod_rewrite method.

      A robust server level method. Your PHP code does not get run before this method happens. This uses the Apache mod_rewrite module allow commands like RewriteCond and RewriteRule to be used. Also, the nice thing about this method is it can be used directly in an .htaccess document at the root of a website to influence all child content in any directory on that site. Or it can be used in a separate directory. The nice thing here since the logic presented is simple if the connection is not HTTPS (RewriteCond %{HTTPS} !on) then just redirect traffic to the HTTPS equivalent (RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}) you can just use this in a common code directory that feeds HTTP and HTTPS and let it do the “worrying.”

      That said, this stuff is utterly not just usable in an .htaccess file but can be used in a server level Apache configuration file. The main difference being that while an .htaccess file can be edited on the fly by any user with read/write access and changes come immediately, if it’s used in an Apache configuration file the user needs to typically have root/sudo access to not only edit the files but also restart the Apache web service to get the rules mod_rewrite rules loaded.

      In general, for a set of RewriteRule commands like this I would actually prefer to place them directly in the server Apache config file—in this case the port 80, plain HTTP configuration block/area—because a config like this is so deep and broad I truly think you would need to only set it once. The negative aspect of this approach compared to the .htaccess method is over time you might also forget you did this. So if you migrate code to a new server and suddenly HTTP connections work, you might panic a bit… And only later on realize you did this. Which is why—in this simple example—I believe the code logic presented is better served by being in an .htaccess file that can be placed in a commonly accessed content directory.

    2. Redirect rule: The Apache server mod_alias method.

      A basic server level method which might fit your “per page” needs better. Your PHP code does not get run before this method happens. This uses the Apache mod_rewrite module allow commands like Alias and Redirect to be used. The best way to see this method is that mod_alias’s first job is to allow you to create aliases that can map a web URL path to a filesystem path. That to me is a very cool ability, but it’s not really applicable towards the issue you describe here which is redirecting plain-HTTP requests to a secure. It’s secondary function is to create a web-URL alias it calls a Redirect, which is simple way to redirect traffic.

      For your simple requirement, the Redirect command can be used for fairly “lunk-headed” redirect tasks and is useful there. But for anything that requires anything slightly more finessed, it’s not useful. Which might be useful to you?

      In the example you posted, you are showing the <VirtualHost *:80> configuration block which would be a part of a larger Apache server-side configuration that would require root/sudo access to set. But honestly the core Redirect "/" "https://www.example.com/" is all you need and you can just place that in an .htaccess file on the plain-HTTP site as well if you wish. Depending on the complexity of your site’s code and your own personal comfort, having this Redirect in an .htaccess file might be the best “set it and forget it” solution. One line, clean, readable and understandable.

    3. Redirect PHP: The code-based method.

      Now this technically works, but you should only really use stuff like this if you have deeper coding logic and needs. Meaning—for example—you have a website whose public front-facing presence really doesn’t need HTTPS and would prefer to leave it at HTTP—since HTTP requires less system overhead than HTTPS—and only redirect to an HTTPS connection after some code logic triggers. Like an administrator login or something like that.

      The negative aspect to this method is unless you have a centralized PHP controller file then this becomes a pain in the butt to maintain. Also, if the redirect happens in PHP and not on a server level, that means that technically any connection to the server will need to parse the PHP logic before knowing what to do. This adds a slight overhead to your codebase since PHP needs to be parsed and might open up a potential code vulnerability that could effectively disable the HTTPS code. Meaning, when websites get hacked that really does not happen on the Apache web server level but rather the coding level where stuff like PHP happens. If HTTPS and security is important to you, relying on PHP code alone to handle redirection decision making and connection enforcement might be a bad idea.

    And one small final note, here is a breakdown of which placement method os more/less resource intensive and user versus admin level access:

    1. Apache mod_rewrite or mod_alias commands directly in the Apache config file. Least resource intensive, but requires root/sudo level access to config and access.
    2. Apache mod_rewrite or mod_alias commands in an .htaccess file. Slightly more resource intensive on the server since Apache has to parse the .htaccess file on each request, but honestly unless your server is incredibly high in traffic or disturbingly resource starved, you won’t notice a speed difference with an .htaccess file. And is nice since you can be a plain/non-root user with read/write access to adjust.
    3. PHP code logic. Least efficient since PHP needs to be parsed for the logic to be executed. And since it happens after the other Apache stuff happens, slight edge-risk of a security vulnerability. But the benefit is you can be a plain/non-root user with read/write access to adjust logic if needed. And you can do more complex things with your PHP logic based on your code needs without having to learn what is essentially another language if you attempted the same logic with mod_rewrite.

    Bonus: How to debug stuff like this from the command line.

    When dealing with redirects and stuff like this, reloading a web browser can be a pain and inaccurate. When you load a webpage for testing like this the full content—including assets—needs to be downloaded and cached by the browser. Not only that, cached content needs to be cleared for a test to work. Really resource intensive for this kind of debugging. Instead, I recommend using a curl -I command from the command line to debug returned headers which I find to be an easier and cleaner way to debug things like this.

    First set the commands in your .htaccess file like this:

    Redirect "/" "https://www.example.com/"
    

    Save it on the server and then run a curl -I command like this:

    curl -I http://www.example.com/
    

    The returned output should be something like this:

    HTTP/1.1 302 Found
    Date: Tue, 22 Dec 2015 01:43:32 GMT
    Server: Apache/2.2.23 (Unix) mod_ssl/2.2.23 OpenSSL/0.9.8zg DAV/2 PHP/5.4.10
    Location: https://www.example.com/
    Content-Type: text/html; charset=iso-8859-1
    

    Note the first HTTP header at the top and the Location: value near the bottom. The 302 Found means the redirect is temporary an the Location: https://www.example.com/ tells the browser where to redirect to.

    That said, in a case like this you might want to change that Redirect in .htaccess to set the header to a 301 Moved Permanently header which is better for SEO and honestly is describing what you are doing; all HTTP traffic is being permanently redirected to HTTPS. You would do that by charing this:

    Redirect "/" "https://www.example.com/"
    

    To this:

    Redirect 301 "/" "https://www.example.com/"
    

    Simply adding that 301 after the Redirect is all you need to do. And after that is done, check the headers again with curl -I http://www.example.com/ and the output should now be:

    HTTP/1.1 301 Moved Permanently
    Date: Tue, 22 Dec 2015 01:54:51 GMT
    Server: Apache/2.2.23 (Unix) mod_ssl/2.2.23 OpenSSL/0.9.8zg DAV/2 PHP/5.4.10
    Location: https://www.example.com/
    Content-Type: text/html; charset=iso-8859-1
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)