LoginSignup
4
3

More than 5 years have passed since last update.

CakePHP3 の Http Client でオレオレ証明書のサーバにSSL接続

Last updated at Posted at 2015-12-05

今回は、CakePHP 3 の小ネタになります。

おそらく PHP 5.6 以降の問題になると思うのですが、OpenSSL 関連の仕様変更に伴い少しハマった場合の対処法を紹介しようと思います。

Cake\Network\Http\Client でオレオレ証明書のサーバに接続しようとして以下のエラーが発生してしまいました。


Exception: fopen(): Peer certificate CN=`hogehoge' did not match expected CN=`fugafuga' 
fopen(): Failed to enable crypto

内部で利用しているストリームラッパーが PHP 5.6 からデフォルトで証明書とホスト名をチェックするようになったようです。
参考:http://php.net/manual/ja/migration56.incompatible.php#migration56.incompatible.peer-verification

そこで、オプションで証明書とホスト名を無視する設定が必要なのですが、Client の内部で使用されている Stream クラスは、ホスト名を無視するための verify_peer_name を渡すことができないようです。

同様の問題が CakePHP 2.x でも起こっていて issue が上がっていましたが、却下されてしまいました。
https://github.com/cakephp/cakephp/issues/7078

サーバーや証明書は、取引先が用意したものなので修正はできません・・・。さて、どうしようかと悩んだのですが、Client に Stream クラスを継承したアダプタをセットすることにしました。

CustomAdapter.php
<?php
use Cake\Network\Http\Adapter\Stream;
use Cake\Network\Http\Request;

class CustomAdapter extends Stream
{
    protected function _buildSslContext(Request $request, $options)
    {
        parent::_buildSslContext($request, $options);

        // 強制的にオプションを設定
        $this->_sslContextOptions['verify_peer'] = false;
        $this->_sslContextOptions['verify_peer_name'] = false;
    }
}

使うときは、

// オプション指定
$client = new Client(['adapter' => 'CustomAdapter']);

とオプションに指定します。ただし、証明書を無視する設定は、セキュリティ的によろしくないので、このアダプターは開発時のみに使用し、本番には指定しないようにしましょう。

このように、CakePHP のクラスのメソッドやパラメータは、public か protected で定義されているので、困った時は継承して、柔軟に対応することができるます。

コアのソースを追って行けば案外なんとかなって、いいフレームワークですね!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3