Axiosを使用してAPIエンドポイントにリクエストを送信しようとすると、次のエラーが発生します:Error: unable to verify the first certificate
Axiosが使用するhttpsモジュールが、サーバーで使用されているSSL証明書を確認できないようです。
ブラウザでサーバーにアクセスすると、証明書は有効であり、表示/ダウンロードできます。また、httpsを介してブラウザーでAPIにリクエストを送信することもできます。
検証をオフにすることで回避できます。このコードは機能します。
const result = await axios.post(
`https://${url}/login`,
body,
{
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
}
)
問題は、これはSSL証明書を検証しないため、セキュリティホールが開かれることです。
証明書を信頼して正しく検証するようにaxiosを構成するにはどうすればよいですか?
古い質問ですが、ここに上陸した人のために鳴り響きます。専門家はいません。お近くのセキュリティ専門家に相談してください。
Axiosはhttp(s)クライアントであり、httpクライアントは通常匿名でTLSに参加します。つまり、サーバーは誰が接続しようとしているかを特定せずに接続を受け入れます。これは、サーバーとクライアントの両方がハンドシェイクを完了する前にお互いを確認する相互TLSとは異なります。
インターネットは恐ろしい場所であり、私たちはクライアントが偽のパブリックエンドポイントに接続しないように保護したいと考えています。これを行うには、クライアントがプライベートデータを送信する前にサーバーを識別できるようにします。
// DO NOT DO THIS IF SHARING PRIVATE DATA WITH SERVICE
const httsAgent = new https.Agent({ rejectUnauthorized: false });
これは多くの場合、あらゆる言語でのhttpsクライアント接続の失敗に関するStackOverflowの回答として投稿されます(そして、より慎重に賛成されます)。そしてさらに悪いことに、それは通常は機能し、開発者のブロックを解除し、彼らは陽気な方法で移動します。しかし、彼らは確かにドアに入りますが、誰のドアですか?彼らはサーバーのIDの検証をオプトアウトしたため、貧弱なクライアントは、会社のイントラネットに対して行ったばかりの接続で、回線を傍受している悪役がいるかどうかを知る方法がありません。
サービスにパブリックSSL証明書がある場合、オペレーティングシステムは公的に信頼されたCA証明書の共通セットを提供するため、通常、https.Agent
をさらに設定する必要はありません。これは通常、ブラウザーが使用するように構成されているCA証明書と同じセットであり、デフォルトのaxiosクライアントが少しの手間で https://google.com をヒットできるのはこのためです。
サービスにプライベートSSL証明書(テスト目的で自己署名したもの、または社内の秘密を保護するために会社のプライベートCAによって署名したもの)がある場合、サーバー証明書の署名に使用するプライベートCAを信頼するようにhttpsエージェントを構成する必要があります。
const httpsAgent = new https.Agent({ ca: MY_CA_BUNDLE });
ここで、MY_CA_BUNDLE
は、.pem
形式のCA証明書の配列です。
SSL証明書を使用してカスタムエージェントを作成します。
const httpsAgent = new https.Agent({
rejectUnauthorized: false, // (NOTE: this will disable client verification)
cert: fs.readFileSync("./usercert.pem"),
key: fs.readFileSync("./key.pem"),
passphrase: "YYY"
})
axios.get(url, { httpsAgent })
// or
const instance = axios.create({ httpsAgent })
これらの構成は私にとっては機能します(相互認証シナリオの場合)。
const httpsAgent = new https.Agent({
ca: fs.readFileSync("./resource/bundle.crt"),
cert: fs.readFileSync("./resrouce/thirdparty.crt"),
key: fs.readFileSync("./resource/key.pem"),
})
注:bundle.crtは、提供された証明書(ルート、中間、エンドエントリの証明書)から作成されました。残念ながら、これに関して明確な文書は見つかりませんでした。