【问题标题】:How to detect secure connection (https) using PHP?如何使用 PHP 检测安全连接(https)?
【发布时间】:2013-02-13 00:48:44
【问题描述】:

目前我的服务器上已包含 SSL。想要强制我的用户通过 https 使用登录页面登录。

<?php

  if (empty($_SERVER['https']) || $_SERVER['https'] != 'on') {
    header('location: https://my_login_page');
    exit();
    }

  # rest of code
  ...

但如果没有 SSL,就会出现问题。

现在我有情况了。用户请求以下 URL

http://domain.com/login.php

在这里,我无法访问$_SERVER['https'],我想确保可以将用户重定向到

https://domain.com/login.php

例如,SSL 证书在一段时间后过期,并希望让用户使用无安全连接的登录。

我的目标是这样的例子:

if (ssl_installed() && (empty($_SERVER['https']) || $_SERVER[] != 'on')) {
  header('location: https://domain.com/login.php');
  exit();
  }

# when there's no SSL it continues using HTTP

是的,想编写函数(例如:ssl_installed()),当可以使用安全连接时返回true,否则返回false

我尝试使用 get_headers() 并意识到它总是针对 https:// 链接返回 false。

可能的解决方案:

我已经有了可行的解决方案。我数据库中的配置表包含行ssl=1(或0),在建立数据库连接后,我使用这个值来决定是否可以使用SSL,上面提到的函数使用这个值来返回结果。

我的问题是:有更简单的解决方案吗?

明确一点:我正在寻找 PHP-ONLY SOLUTION(自动检测)!

任何帮助将不胜感激。

【问题讨论】:

  • 您使用的所有 php 文件中是否都有通用配置文件?比如config.php?
  • @sjdaws 当然是的,我保留了用于 PDO 的数据库帐户信息。
  • $_SERVER["HTTPS"](大写字母)是否存在? PHP doc
  • @Passerby - 在我的服务器上同时使用 https 和 HTTPS。但是 HTTP 请求中不存在 $_SERVER['HTTPS'] 并且没有告诉我是否可以使用 https:// 而不是 http:// 将页面重定向到相同的页面。

标签: php security ssl https


【解决方案1】:

我认为您可以使用 htaccess 解决这个问题,这两个条件可能会有所帮助

  • RewriteCond %{HTTP:X-Forwarded-SSL} on
  • RewriteCond %{HTTPS} 开启

有关更多信息,请参阅此答案:https://stackoverflow.com/a/1128624/1712686

【讨论】:

【解决方案2】:

您可以在配置文件中执行类似的操作,而不是编辑每个脚本。

<?php

// will match /login.php and /checkout.php as examples
$force_ssl = preg_match('/\/(login|checkout)\.php(.+)?/', $_SERVER['REQUEST_URI']);
$using_ssl = (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ? true : false;

$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

if ($force_ssl && !$using_ssl) {

    // redirect to SSL
    header('Location: https://' . $url);

} elseif (!$force_ssl && $using_ssl) {

    // redirect back to normal
    header('Location: http://' . $url);

}

如果您的证书过期,只需在您的配置文件中将$force_ssl 设置为false,它就会处理之前重定向的每个脚本。


现在问题已经澄清了,你可以创建一个这样的 PHP 脚本(代码取自 https://stackoverflow.com/a/4741196/654678

<?php

// get and check certificate
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));
$read = stream_socket_client("ssl://www.google.com:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
$cert = stream_context_get_params($read);

$valid = ($cert["options"]["ssl"]["peer_certificate"] != NULL) ? true : false;

// save validity in database or somewhere else accessible

然后设置一个 crontab,或每日任务或其他任何东西来每天点击那个 PHP 脚本。如果没有证书,它将返回 NULL 并标记为无效。用你的脚本检查有效性,你就可以开始了。

【讨论】:

  • 为您的努力+1。我现在已经有类似的解决方案。我只是在寻找一种方法来自动确定服务器上的 SSL,而无需手动设置 SSL 状态(在配置、数据库等中)。顺便说一句,您的 $using_ssl 分配行不正确,因为在 IIS 服务器上 $_SERVER['HTTPS'] 始终设置为非空值('on' 或 'off'),如果设置它不能为空。跨度>
  • 那么你想让PHP检测是否在服务器级别安装了证书?
  • 肮脏的解决方案,但仍然是解决方案。甚至,这并不是我真正想要的,你答案的底部帮助我找到了很多解决方案(使用 cron)。谢谢
  • 您在 "$using_ssl = (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ? true : false;" 行中有语法错误,您需要在“?true : false;”之前添加另一个“)”部分,我无法编辑它,所以我只是让您知道,以便您修复它
【解决方案3】:
/**
 * Return true if HTTPS enabled  otherwise return false
 */
function check_ssl() {
  if ( isset( $_SERVER['HTTPS'] ) ) {
    if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) {
      return true;
    } elseif ( '1' == $_SERVER['HTTPS'] ) {
      return true;
    }
  }

  if ( isset( $_SERVER['SERVER_PORT'] )
    && ( '443' == $_SERVER['SERVER_PORT'] ) 
  ) {
    return true;
  }

  return false;
}

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 2019-07-22
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2013-03-09
    • 2017-11-27
    相关资源
    最近更新 更多