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

Wh1*_*Ck5 0 php security ssl https

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

<?php

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

  # rest of code
  ...
Run Code Online (Sandbox Code Playgroud)

但是当没有SSL时,这是一个问题.

现在我有情况.用户请求关注URL

http://domain.com/login.php
Run Code Online (Sandbox Code Playgroud)

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

https://domain.com/login.php
Run Code Online (Sandbox Code Playgroud)

例如,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
Run Code Online (Sandbox Code Playgroud)

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

我已经尝试过使用get_headers()并意识到它总是会对https://链接返回false .

可能的方法:

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

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

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

任何帮助,将不胜感激.

sjd*_*aws 5

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

<?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);

}
Run Code Online (Sandbox Code Playgroud)

然后,如果您的证书到期,只需设置$force_sslfalse您的配置文件,它会采取所有这在以前重定向脚本的照顾.


现在问题已经澄清,您可以创建这样的PHP脚本(代码取自/sf/answers/331883751/)

<?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
Run Code Online (Sandbox Code Playgroud)

然后设置一个crontab,或每日任务或每天点击该PHP脚本的任何内容.如果没有证书,它将返回NULL并被标记为无效.用脚本检查有效性,你就可以了.

  • +1为你的努力.我已经有类似的解决方案,我现在使用.我只是在寻找一种方法来自动确定服务器上的SSL,无需手动设置SSL状态(在配置,数据库等).顺便说一下,使用$ using_ssl赋值的行是不正确的,因为在IIS服务器上$ _SERVER ['HTTPS']总是设置为非空值('on'或'off'),如果设置它就不能为空. (2认同)