javascript - 無法驗證葉節點簽章
我正在使用 node.js 的 request.js 來訪問一個 API。我收到了這個錯誤
[錯誤:無法驗證憑證簽章]
我所有的憑證都是準確且有效的,伺服器也沒問題。我用 Postman 發送了相同的請求。
request({
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
這段程式碼只是作為可執行腳本運行,例如 node ./run_file.js,是這個原因嗎?它需要在伺服器上運行嗎?
答案#1
注意:以下內容具有危險性,將允許在客戶端與伺服器之間攔截並修改 API 內容。
這也有效
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';答案#2
安全解決方案
與其關閉安全性,你可以將必要的憑證加入鏈中。首先從 npm 安裝 ssl-root-cas 套件:
npm install ssl-root-cas
此套件包含許多瀏覽器信任但 Node 不信任的中介憑證。
var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()
將會補上缺少的證書。更多資訊請見此處:
https://git.coolaj86.com/coolaj86/ssl-root-cas.js
答案#3
這不是應用程式的問題,而是憑證的問題,該憑證是由中介 CA 簽署的。如果你接受這個事實並且仍然想繼續,請將以下內容添加到請求選項中:
rejectUnauthorized: false
完整請求:
request({
"rejectUnauthorized": false,
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
答案#4
CoolAJ86 的解決方案是正確的,並且它不會像使用 rejectUnauthorized 或 NODE_TLS_REJECT_UNAUTHORIZED 禁用所有檢查那樣危及你的安全性。不過,你可能仍然需要明確地注入額外的 CA 證書。
我先嘗試了 ssl-root-cas 模組中包含的根憑證授權機構(CA):
require('ssl-root-cas/latest')
.inject();
我仍然最終遇到了 UNABLE_TO_VERIFY_LEAF_SIGNATURE 錯誤。然後我通過 COMODO SSL 分析器找到了我連接的網站證書的簽發者,下載了該權威機構的證書,並嘗試只添加那一個:
require('ssl-root-cas/latest')
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
我最終遇到了另一個錯誤:CERT_UNTRUSTED。最後,我注入了額外的根 CA 並包含了「我的」(顯然是中介)CA,這樣就成功了:
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
答案#5
對於 Create React App(這個錯誤也會發生在這裡,而且這個問題是 Google 的第一個搜尋結果),你可能在開發時使用 HTTPS=true npm start 和一個 proxy(在 package.json 中),它指向某個自簽名的 HTTPS API。
如果是這種情況,請考慮這樣更改 proxy:
"proxy": {
"/api": {
"target": "https://localhost:5001",
"secure": false
}
}
secure 決定 WebPack 代理是否檢查證書鏈,禁用它可以確保 API 自簽名證書不被驗證,從而讓你獲取數據。
答案#6
可能很想設置 rejectUnauthorized: false 或 process.env['NODE_TLS_REJECT_UNAUTHORIZED']='0';,但不要這麼做!這會讓你暴露於中間人攻擊的風險中。
其他答案是正確的,問題在於你的證書是「由中介 CA 簽署的」。這有一個簡單的解決方法,不需要像 ssl-root-cas 這樣的第三方庫,也不需要向 Node 注入任何額外的 CA。
大多數在 Node 的 https 客戶端都支援允許你為每個請求指定 CA 的選項,這將解決 UNABLE_TO_VERIFY_LEAF_SIGNATURE。這裡是一個使用 Node 內建 https 模組的簡單範例。
import https from 'https';
const options = {
host: '<your host>',
defaultPort: 443,
path: '<your path>',
// assuming the bundle file is co-located with this file
ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
headers: {
'content-type': 'application/json',
}
};
https.get(options, res => {
// do whatever you need to do
})
不過,如果你可以在你的主機伺服器上配置 SSL 設定,最好的解決方案是將中繼證書添加到你的主機提供商。這樣客戶端請求者就不需要指定 CA,因為它已包含在伺服器本身。我個人使用 Namecheap + Heroku。對我來說的技巧是使用 cat yourcertificate.crt bundle.ca-bundle > server.crt 創建一個 .crt 文件。然後我打開這個文件,在第一個證書之後添加了一個換行符。你可以在這裡閱讀更多資訊
https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/在Heroku上安裝SSL憑證
