Nodejs進階:核心模塊https 之 如何優雅的訪問12306

CarlaFryer 8年前發布 | 11K 次閱讀 Node.js Node.js 開發 HTTPS

模塊概覽

這個模塊的重要性,基本不用強調了。在網絡安全問題日益嚴峻的今天,網站采用HTTPS是個必然的趨勢。

在nodejs中,提供了 https 這個模塊來完成 HTTPS 相關功能。從官方文檔來看,跟 http 模塊用法非常相似。

本文主要包含兩部分:

  1. 通過客戶端、服務端的例子,對https模塊進行入門講解。

  2. 如何訪問安全證書不受信任的網站。(以 12306 為例子)

篇幅所限,本文無法對 HTTPS協議 及 相關技術體系 做過多講解,有問題歡迎留言交流。

客戶端例子

跟http模塊的用法非常像,只不過請求的地址是https協議的而已,代碼如下:

var https = require('https');

https.get('

res.on('data', function(data){
    process.stdout.write(data);
});

}).on('error', function(err){ console.error(err); });</code></pre>

服務端例子

對外提供HTTPS服務,需要有HTTPS證書。如果你已經有了HTTPS證書,那么可以跳過證書生成的環節。如果沒有,可以參考如下步驟

生成證書

1、創建個目錄存放證書。

mkdir cert
cd cert

2、生成私鑰。

openssl genrsa -out chyingp-key.pem 2048

3、生成證書簽名請求(csr是 Certificate Signing Request的意思)。

openssl req -new \
  -sha256
  -key chyingp-key.key.pem \
  -out chyingp-csr.pem \
  -subj "/C=CN/ST=Guandong/L=Shenzhen/O=YH Inc/CN=www.chyingp.com"

4、生成證書。

openssl x509 \
  -req -in chyingp-csr.pem \
  -signkey chyingp-key.pem \
  -out chyingp-cert.pem

HTTPS服務端

代碼如下:

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

var options = { key: fs.readFileSync('./cert/chyingp-key.pem'), // 私鑰 cert: fs.readFileSync('./cert/chyingp-cert.pem') // 證書 };

var server = https.createServer(options, function(req, res){ res.end('這是來自HTTPS服務器的返回'); });

server.listen(3000);</code></pre>

由于我并沒有 www.chyingp.com 這個域名,于是先配置本地host

127.0.0.1 www.chyingp.com

啟動服務,并在瀏覽器里訪問 http://www.chyingp.com:3000 。注意,瀏覽器會提示你證書不可靠,點擊 信任并繼續訪問 就行了。

進階例子:訪問安全證書不受信任的網站

這里以我們最喜愛的12306最為例子。當我們通過瀏覽器,訪問12306的購票頁面 https://kyfw.12306.cn/otn/reg... 時,chrome會阻止我們訪問,這是因為,12306的證書是自己頒發的,chrome無法確認他的安全性。

對這種情況,可以有如下處理方式:

  1. 停止訪問:著急搶票回家過年的老鄉表示無法接受。

  2. 無視安全警告,繼續訪問:大部分情況下,瀏覽器是會放行的,不過安全提示還在。

  3. 導入12306的CA根證書:瀏覽器乖乖就范,認為訪問是安全的。(實際上還是有安全提示,因為12306用的簽名算法安全級別不夠)

例子:觸發安全限制

同樣的,通過 node https client 發起請求,也會遇到同樣問題。我們做下實驗,代碼如下:

var https = require('https');

https.get(' res.on('data', function(data){ process.stdout.write(data); }); }).on('error', function(err){ console.error(err); });</code></pre>

運行上面代碼,得到下面的錯誤提示,意思是 安全證書不可靠,拒絕繼續訪問。

{ Error: self signed certificate in certificate chain
    at Error (native)
    at TLSSocket.<anonymous> (_tls_wrap.js:1055:38)
    at emitNone (events.js:86:13)
    at TLSSocket.emit (events.js:185:7)
    at TLSSocket._finishInit (_tls_wrap.js:580:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:412:38) code: 'SELF_SIGNED_CERT_IN_CHAIN' }

ps:個人認為這里的錯誤提示有點誤導人,12306網站的證書并不是自簽名的,只是對證書簽名的CA是12306自家的,不在可信列表里而已。自簽名證書,跟自己CA簽名的證書還是不一樣的。

類似在瀏覽器里訪問,我們可以采取如下處理:

  1. 不建議:忽略安全警告,繼續訪問;

  2. 建議:將12306的CA加入受信列表;

方法1:忽略安全警告,繼續訪問

非常簡單,將 rejectUnauthorized 設置為 false 就行,再次運行代碼,就可以愉快的返回頁面了。

// 例子:忽略安全警告
var https = require('https');
var fs = require('fs');

var options = { hostname: 'kyfw.12306.cn', path: '/otn/leftTicket/init', rejectUnauthorized: false // 忽略安全警告 };

var req = https.get(options, function(res){ res.pipe(process.stdout);
});

req.on('error', function(err){ console.error(err.code); });</code></pre>

方法2:將12306的CA加入受信列表

這里包含3個步驟:

  1. 下載 12306 的CA證書

  2. 將der格式的CA證書,轉成pem格式

  3. 修改node https的配置

1、下載 12306 的CA證書

在12306的官網上,提供了CA證書的 下載地址 ,將它保存到本地,命名為 srca.cer。

2、將der格式的CA證書,轉成pem格式

https初始化client時,提供了 ca 這個配置項,可以將 12306 的CA證書添加進去。當你訪問 12306 的網站時,client就會用ca配置項里的 ca 證書,對當前的證書進行校驗,于是就校驗通過了。

需要注意的是,ca 配置項只支持 pem 格式,而從12306官網下載的是der格式的。需要轉換下格式才能用。

openssl x509 -in srca.cer -inform der -outform pem -out srca.cer.pem

3、修改node https的配置

修改后的代碼如下,現在可以愉快的訪問12306了。

// 例子:將12306的CA證書,加入我們的信任列表里
var https = require('https');
var fs = require('fs');
var ca = fs.readFileSync('./srca.cer.pem');

var options = { hostname: 'kyfw.12306.cn', path: '/otn/leftTicket/init', ca: [ ca ] };

var req = https.get(options, function(res){ res.pipe(process.stdout); });

req.on('error', function(err){ console.error(err.code); });</code></pre>

 

來自:https://segmentfault.com/a/1190000007544239

 

 本文由用戶 CarlaFryer 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!