如何使用PHP检测安全连接(https)


How to detect secure connection (https) using PHP?

目前我的服务器上包含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证书在一段时间后过期,希望用户继续使用登录w/out安全连接。

我的目标是类似于这个例子:

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解决方案(自动检测)!

您可以在配置文件中这样做,而不是编辑每个脚本。

<?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_sslfalse,它就会处理以前重定向的每个脚本。


现在问题已经澄清,您可以创建这样的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并被标记为无效。检查脚本的有效性,就可以开始了。

我想你可以用htaccess来解决这个问题,这两个条件可能会有帮助

  • rewritecsecond %{HTTP:X-Forwarded-SSL} on
  • rewritecsecond %{HTTPS} on

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

/**
 * 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;
}