Próbuję pobrać plik z serwera Jira przy użyciu adresu URL, ale pojawia się błąd. jak dołączyć certyfikat do kodu, aby zweryfikować błąd:
Error: unable to verify the first certificate in nodejs
at Error (native)
at TLSSocket.<anonymous> (_tls_wrap.js:929:36)
at TLSSocket.emit (events.js:104:17)
at TLSSocket._finishInit (_tls_wrap.js:460:8)
Mój kod Nodejs:
var https = require("https");
var fs = require('fs');
var options = {
host: 'jira.example.com',
path: '/secure/attachment/206906/update.xlsx'
};
https.get(options, function (http_res) {
var data = "";
http_res.on("data", function (chunk) {
data += chunk;
});
http_res.on("end", function () {
var file = fs.createWriteStream("file.xlsx");
data.pipe(file);
});
});
node.js
ssl-certificate
jira
Labeo
źródło
źródło
Odpowiedzi:
Spróbuj dodać odpowiedni certyfikat główny
To zawsze będzie znacznie bezpieczniejsza opcja niż ślepe akceptowanie nieautoryzowanych punktów końcowych, które z kolei powinny być używane tylko w ostateczności.
Może to być tak proste, jak dodanie
require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create();
do swojej aplikacji.
Pakiet npm SSL głównej CA (jak tutaj stosowane) jest bardzo przydatny pakiet dotyczące tego problemu.
źródło
$(mkcert -CAROOT)/rootCA.pem
w nowym pliku certyfikatu i zrobić coś takiego:https.globalAgent.options.ca = fs.readFileSync('fullchain.pem')
Zobacz github.com/FiloSottile/mkcert/issues/76ssl-root-cas
moduł npm ma żądanie do mozilla.org zakodowane na sztywno git.coolaj86.com/coolaj86/ssl-root-cas.js/src/branch/master/… . Prawdopodobnie jest to bezpieczne, ponieważ Mozilla, ale wygląda na wektor ataku.Kolejny brudny hack, który sprawi, że wszystkie twoje żądania będą niepewne:
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
źródło
unable to verify the first certificate
Łańcuch certyfikatów jest niekompletny.
Oznacza to, że serwer sieciowy, z którym się łączysz, jest źle skonfigurowany i nie zawiera certyfikatu pośredniego w łańcuchu certyfikatów, który do Ciebie wysłał.
Łańcuch certyfikatów
Najprawdopodobniej wygląda to następująco:
Certyfikat pośredni powinien być zainstalowany na serwerze wraz z certyfikatem serwera.
Certyfikaty główne są wbudowane w aplikacje, przeglądarki i systemy operacyjne.
Aplikacja obsługująca certyfikat musi wysłać cały łańcuch, czyli sam certyfikat serwera i wszystkie pośredniki. Certyfikat główny powinien być znany klientowi.
Odtwórz problem
Przejdź do https://incomplete-chain.badssl.com za pomocą przeglądarki.
Nie pokazuje żadnego błędu (kłódka w pasku adresu jest zielona).
Dzieje się tak, ponieważ przeglądarki zwykle uzupełniają łańcuch, jeśli nie jest on wysyłany z serwera.
Teraz połącz się z https://incomplete-chain.badssl.com za pomocą Node:
// index.js const axios = require('axios'); axios.get('https://incomplete-chain.badssl.com') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
Dzienniki: „ Błąd: nie można zweryfikować pierwszego certyfikatu ”.
Rozwiązanie
Musisz samodzielnie uzupełnić łańcuch certyfikatów.
Aby to zrobić:
1: W takim razie musisz zdobyć brakujący certyfikat pośredni w
.pem
formacie2a: rozszerz wbudowany magazyn certyfikatów Node za pomocą
NODE_EXTRA_CA_CERTS
,2b: lub przekaż własny pakiet certyfikatów (pośrednie i root) za pomocą
ca
opcji.1. Jak uzyskać certyfikat pośredni?
Używanie
openssl
(dostarczane z Git dla Windows ).Zapisz szczegóły certyfikatu zdalnego serwera:
openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile
Poszukujemy wystawcy (certyfikat pośredni to wystawca / podpisujący certyfikat serwera):
openssl x509 -in logcertfile -noout -text | grep -i "issuer"
Powinien dać Ci identyfikator URI certyfikatu podpisującego. Pobierz to:
curl --output intermediate.crt http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
Na koniec przekonwertuj go na
.pem
:openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text
2a. NODE_EXTRA_CERTS
Używam cross-env do ustawiania zmiennych środowiskowych w
package.json
pliku:"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"
2b.
ca
opcjaTa opcja spowoduje nadpisanie wbudowanych głównych urzędów certyfikacji węzła.
Dlatego musimy stworzyć własny główny urząd certyfikacji. Użyj ssl-root-cas .
Następnie utwórz niestandardowego
https
agenta skonfigurowanego za pomocą naszego pakietu certyfikatów (root i pośredni). Przekaż tego agentaaxios
podczas składania wniosku.// index.js const axios = require('axios'); const path = require('path'); const https = require('https'); const rootCas = require('ssl-root-cas').create(); rootCas.addFile(path.resolve(__dirname, 'intermediate.pem')); const httpsAgent = new https.Agent({ca: rootCas}); axios.get('https://incomplete-chain.badssl.com', { httpsAgent }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
Zamiast tworzyć niestandardowego
https
agenta i przekazywać goaxios
, możesz umieścić certyfikaty whttps
globalnym agencie:// Applies to ALL requests (whether using https directly or the request module) https.globalAgent.options.ca = rootCas;
Zasoby:
źródło
za niemożność zweryfikowania pierwszego certyfikatu w nodejs konieczne jest odrzucenie nieautoryzowanego
request({method: "GET", "rejectUnauthorized": false, "url": url, "headers" : {"Content-Type": "application/json", function(err,data,body) { }).pipe( fs.createWriteStream('file.html'));
źródło
Serwer, z którego próbujesz pobrać, może być źle skonfigurowany. Nawet jeśli działa w Twojej przeglądarce, może nie zawierać wszystkich publicznych certyfikatów w łańcuchu potrzebnych do weryfikacji przez klienta z pustą pamięcią podręczną.
Polecam sprawdzić stronę w narzędziu SSLlabs: https://www.ssllabs.com/ssltest/
Poszukaj tego błędu:
I to:
źródło
cat domainname.crt domainname.ca-bundle > domainname-ssl-bundle.crt
To faktycznie rozwiązało to dla mnie, od https://www.npmjs.com/package/ssl-root-cas
// INCORRECT (but might still work) var server = https.createServer({ key: fs.readFileSync('privkey.pem', 'ascii'), cert: fs.readFileSync('cert.pem', 'ascii') // a PEM containing ONLY the SERVER certificate }); // CORRECT (should always work) var server = https.createServer({ key: fs.readFileSync('privkey.pem', 'ascii'), cert: fs.readFileSync('fullchain.pem', 'ascii') // a PEM containing the SERVER and ALL INTERMEDIATES });
źródło
Możesz to zrobić, modyfikując opcje żądania, jak poniżej. Jeśli używasz certyfikatu z podpisem własnym lub brakującego pośrednika, ustawienie parametru strictSSL na false nie wymusi żądania pakietu w celu zweryfikowania certyfikatu.
var options = { host: 'jira.example.com', path: '/secure/attachment/206906/update.xlsx', strictSSL: false }
źródło
To zadziałało dla mnie => dodawanie agenta i 'odrzucenieUnauthorized' ustawione na false
const https = require('https'); //Add This const bindingGridData = async () => { const url = `your URL-Here`; const request = new Request(url, { method: 'GET', headers: new Headers({ Authorization: `Your Token If Any`, 'Content-Type': 'application/json', }), //Add The Below agent: new https.Agent({ rejectUnauthorized: false, }), }); return await fetch(request) .then((response: any) => { return response.json(); }) .then((response: any) => { console.log('response is', response); return response; }) .catch((err: any) => { console.log('This is Error', err); return; }); };
źródło
Certyfikat GoDaddy SSL CCertificate
Doświadczyłem tego, próbując połączyć się z naszym serwerem API zaplecza z certyfikatem GoDaddy i oto kod, którego użyłem do rozwiązania problemu.
var rootCas = require('ssl-root-cas/latest').create(); rootCas .addFile(path.join(__dirname, '../config/ssl/gd_bundle-g2-g1.crt')) ; // will work with all https requests will all libraries (i.e. request.js) require('https').globalAgent.options.ca = rootCas;
PS:
Skorzystaj z dołączonego certyfikatu i nie zapomnij zainstalować biblioteki
npm install ssl-root-cas
źródło
Innym sposobem rozwiązania tego problemu jest użycie następującego modułu.
node_extra_ca_certs_mozilla_bundle
Moduł ten może działać bez modyfikacji kodu, generując plik PEM zawierający wszystkie certyfikaty główne i pośrednie zaufane przez Mozillę. Możesz użyć następującej zmiennej środowiskowej (działa z Nodejs v7.3 +),
NODE_EXTRA_CA_CERTS
Aby wygenerować plik PEM do użycia z powyższą zmienną środowiskową. Moduł możesz zainstalować za pomocą:
a następnie uruchom skrypt węzła ze zmienną środowiskową.
Inne sposoby wykorzystania wygenerowanego pliku PEM są dostępne pod adresem:
https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle
UWAGA: jestem autorem powyższego modułu.
źródło
Używałem modułu Nodemailer npm. Poniższy kod rozwiązał problem
tls: { // do not fail on invalid certs rejectUnauthorized: false }
źródło