自作プラグインから自作APIプラグインをコールするとき: 秘密コードの漏洩を厳密に防止したい
2025年3月6日 14時59分 [akaz]こんにちは!
今回はひとつ要望がありまして投稿しております。先日の投稿にも書きましたが、私は今、自作プラグインと自作APIプラグインとを作り、「自作プラグイン」 → 「自作APIプラグイン」 → 「外部サービスのコール」という流れをテストしているところです。
ひとつ気づいたのですが、APIコールするときに、無認可の者に直接APIを叩かれないように、secret code(秘密コード)をURLに含められる形になっていますよね。
- 「秘密コード」とは「管理者メニュー」→「API管理」で設定するもののことです。
- ApiPluginBase.php の apiCallCheck()メソッドのコードを確認しました。
懸念点
APIプラグインを同一ホスト内の別のプラグインからコールするのであれば、URL(秘密コード含む)がインターネットにさらされることはありませんが、次の点が懸念材料です。
(1) webサーバのアクセスログに秘密コードが保存されうる点。アクセスログは誰が見ることができ、どのように管理されるのか、状況によっては心配の元となるため。
(2) Connect-CMSサイトの外部からAPIコールする用途では、URL(秘密コード)がインターネットにさらされる点。
要望
自作の通常プラグイン(あるいは外部サイトから)、HTTPヘッダーに「Authorization: Bearer 」を含める形で、APIをコールできるようにして欲しいです。言い換えると、apiCallCheck() に Authorization ヘッダーのチェック機能を実装して欲しいです。
コード例は以下のとおりです。これであれば、現状の GET で URLパラメータに秘密コードを含む方法とも互換性があります。
public function apiCallCheck($request, $plugin_name)
{// まず `Authorization` ヘッダーを確認
$auth_header = $request->header('Authorization');
if (!empty($auth_header) && preg_match('/Bearer\s+(.+)/', $auth_header, $matches)) {
$secret_code = $matches[1];
}
// `Authorization` ヘッダーがない場合は `GET` パラメータを確認
elseif ($request->filled('secret_code')) {
$secret_code = $request->secret_code;
} // どちらもない場合はエラー
else {
return array('code' => 403, 'message' => '秘密コードが必要です。');
}
// 以降は今の `apiCallCheck()` と同じ処理
/* 後略 */}
apiCallCheck()メソッドが上記のようになっていれば、自作プラグインなどから、例えば、以下のようなコードで安全にAPIをコールできます。(下のコードでは、環境変数に秘密コードを保存しておく形としていますが、もっとよい方法もあるでしょう。)
// Secret code を Authorization ヘッダーで渡す
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . env('SECRET_CODE')
])->get($url);
以上、ご検討いただけますでしょうか。よろしくお願いいたします。