2012-04-13 33 views
6

Chương trình thử nghiệm này kết nối với máy chủ https và nhận một số nội dung. Tôi đã kiểm tra máy chủ của mình trong trình duyệt và với curl và chứng chỉ đang hoạt động chính xác. Nếu tôi chạy curl để lấy dữ liệu từ máy chủ, nó chính xác phàn nàn về chứng chỉ chưa được biết trừ khi tôi chuyển nó vào với --cacert hoặc tắt bảo mật bằng -k.Ứng dụng https node.js của tôi luôn hoạt động bất kể giá trị của chứng chỉ

Vì vậy, vấn đề tôi gặp phải là mặc dù tôi nghĩ rằng khách hàng của tôi phải thực hiện xác thực chứng chỉ và tôi đang nói nó ở đâu chứng chỉ công khai, nó luôn hoạt động. Nếu tôi loại bỏ ca: tùy chọn để nó không có ý tưởng những gì chứng chỉ là từ máy chủ sau đó nó âm thầm hoạt động. Tôi muốn bắt lỗi xác thực nhưng tôi không thể làm như vậy.

var https = require('https'); 
var fs = require('fs'); 

function main() { 

     var data = ''; 

     var get = https.get({ 
     path: '/', 
     host: 'localhost', 
     port: 8000, 
     agent: false, 
     ca: [ fs.readFileSync('https_simple/cacert.pem') ] 

     }, function(x) { 

     x.setEncoding('utf8'); 
     x.on('data', function(c) {data += c}); 
     x.on('error', function(e) { 
      throw e; 
     }); 
     x.on('end', function() { 
      console.log('Hai!. Here is the response:'); 
      console.log(data); 
     }); 

     }); 

     get.on('error', function(e) {throw e}); 

     get.end(); 

    } 

main(); 

Trả lời

10

Để thực hiện công việc này tôi cần phải nâng cấp lên v0.7.8 (mặc dù bất kỳ v0.7 nên sử dụng tốt), nơi các chức năng rejectUnauthorized đã được thêm vào https.get

Sự kết hợp này các tùy chọn là cần thiết:

agent: false, // or you can supply your own agent, but if you don't you must set to false 
rejectUnauthorized: true, 
ca: [ fs.readFileSync('https_simple/cacert.pem') ] 

Bây giờ nếu xác thực thất bại, bạn sẽ nhận được sự kiện 'lỗi' và yêu cầu sẽ không tiếp tục.

Xem https.request documentation biết chi tiết về làm chất độc của riêng bạn

Việc sửa chữa lỗi đã được cam kết trong sự thay đổi này: https://github.com/joyent/node/commit/f8c335d0

+1

rejectUnauthorized được thêm vào trong phiên bản 0.7.0 –

+2

Nhìn vào tài liệu: http://nodejs.org/api/tls.html, không có dấu hiệu nào cho thấy rằng 'rejectUnauthorized' đã được thêm vào cho máy khách ... cho máy chủ có nhưng không phải là máy khách. .. bạn có thể vui lòng đặt tôi trên con đường bên phải ở đây không? Tôi có đang xem tài liệu lỗi thời ở đây không? – pulkitsinghal

+0

Danh sách thay đổi nằm trong câu trả lời ở trên. Vấn đề đã được theo dõi ở đây https://github.com/joyent/node/issues/2247 Tôi đã không xem xét liệu các tài liệu được cập nhật mặc dù, xin lỗi. – justinhj

4

Theo documentation cho https.request, các ca lựa chọn của cả hai https.gethttps.request là một lựa chọn từ tls.connect. Tài liệu về các tùy chọn đối với chức năng mô-đun tls.connect mô tả:

ca: Một chuỗi các chuỗi hoặc Bộ đệm chứng chỉ đáng tin cậy. Nếu đây là bỏ qua một số CA "gốc" nổi tiếng sẽ được sử dụng, như VeriSign. Chúng được sử dụng để cho phép kết nối.

Đào vào nguồn Node.js, các Certs gốc được sử dụng có thể tìm thấy ở đây: https://github.com/joyent/node/blob/master/src/node_root_certs.h

Vì vậy, trong ngắn hạn, không có cert thẩm quyền cung cấp như một tùy chọn để https.get module tls sẽ cố gắng để xác thực kết nối bằng cách sử dụng danh sách các certs gốc anyway.

+1

Đó là thông tin tốt nhờ. Nó không giúp tôi ở đây, bởi vì tôi đang sử dụng chứng chỉ tự ký của riêng mình. Tôi hy vọng kết nối chỉ hoạt động nếu tôi vượt qua chứng chỉ của mình, nhưng nó hoạt động theo một trong hai cách. – justinhj

+0

@ Перо là có một số cách để kết hợp cert máy chủ và không bị mất các CA gốc? Ví dụ: 'ca: [fs.readFileSync ('myServerCert.pem '), node_root_certs.h] 'Cú pháp để truy cập hằng số trong tệp tiêu đề là gì? – pulkitsinghal

1

Trong V 0.6.15 bạn cần phải explicitly check việc xác thực chứng chỉ có vượt qua hoặc không thành công hay không.

if (x.connection.authorized === false) {  
    console.log('SSL Authentication failed'); 
} else if (x.connection.authorized === true) {  
    console.log('SSL Authentication succeeded'); 
} 
+0

Điều đó có vẻ đầy hứa hẹn nhưng x.authorized không xác định – justinhj

+0

@justinhj, tôi đã sửa mã trong câu trả lời. –

+0

Có lẽ, điều này có nghĩa là được đặt trong chức năng gọi lại. Thật không may, điều này không ngăn yêu cầu được thực hiện khi chứng chỉ không đáng tin cậy, nó chỉ cho bạn biết khi nó được thực hiện (ví dụ, bạn có thể đã bị rò rỉ thông tin xác thực). – Bruno

2

Tôi làm điều này trong NPM, sử dụng các mô-đun request. Nó giống như sau:

var cacert = ... // in npm, this is a config setting 
var request = require("request") 
request.get({ url: "https://...", 
       ca: cacert, 
       strictSSL: true }) 
    .on("response", function (resp) { ... }) 
    .on("error", function (er) { ... }) 

Sự kiện lỗi sẽ được nâng lên nếu ssl không hợp lệ.

Các vấn đề liên quan