CakePHP4で他サービス(ドメインが違う)から呼ばれるWebAPIのセキュリティを考える
自社でCakePHP4の社内ツールを作っているのですが、同じように社内ツールを作っている別チームからうちのサービスで管理している情報にアクセスしたい要求があり、APIを作ることになりました。別にその機能だけ考えるなら、ちゃちゃっと出来そうな感じだったんですが、誰からでも呼び出せるとなるとちょっとよろしくないかなと思い、ちょっとセキュリティについて調べることにしました。まぁCakePHPに限った話ではないのですがね。

LINEのMessaging APIでも参考にしてれば大丈夫かな
と思い、別のところでGoogle Apps Scriptを使ってGMailを監視して特定のメールが来たらLINEで教えてもらえる処理を作っていたので、どうだったか確認しましたらHTTPヘッダーのAuthorizationに決められたトークン入れてるだけでした。それでいいか。まぁ32文字くらいの大小英数を組み合わせた乱数なら総当たりでも厳しいだろうけど。もし間違ったトークンだったら5秒くらい応答しない嫌がらせしておけば総当たりの効率下げられるかなとも思ったけど、自社サーバーのPHPは同時アクセス時はどんな挙動するのか不明なんでちょっと調査してみないと。他のリクエストに影響出ちゃうとよくないしねぇ。
テストコードを書いて確認してみる
とりあえずCakePHP4の環境をComposerで2つ作って片側からGetでもう一方にアクセスしてヘッダーのAuthorizationを取得してみようかと思います。
composer self-update
composer create-project --prefer-dist cakephp/app:"4.*" test-app1
composer create-project --prefer-dist cakephp/app:"4.*" test-app2<?php
namespace App\Controller;
use Cake\Http\Client;
use Cake\Log\Log;
class TestController extends AppController
{
public function index()
{
$http = new Client(['headers' => ['Authorization' => 'Bearer 12345678']]);
$response = $http->get('http://localhost:10082/Test/');
$this->set('response', $response->getStringBody());
return $this->render();
}
}<?= $response ?><?php
namespace App\Controller;
use Cake\Http\Client;
use Cake\Log\Log;
class TestController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
public function index()
{
$this->set('Authorization', $this->request->getHeaderLine('Authorization'));
$this->viewBuilder()
->setClassName('Json')
->setOption('serialize', ['Authorization'])
->setOption('jsonOptions', JSON_FORCE_OBJECT);
}
}コードができたのでそれぞれ起動してみます。
test-app1/bin/cake server -p 10081
test-app2/bin/cake server -p 10082ブラウザで表示してみるとヘッダーのAuthorizationの送信と受信に成功しているようです。

まとめ
サーバー間で呼び出すAPIのセキュリティはヘッダーのAuthorizationを使うことにします。ヘッダーだけ見るとOAuth2っぽいですがトークンが永続的なんでちょっと違いますかね。トークンがクライアントに渡されるわけじゃないから、まぁこれでいいんでしょう。
