设为首页 收藏本站
查看: 1091|回复: 0

[经验分享] Nodejs进阶:核心模块https 之 如何优雅的访问12306

[复制链接]

尚未签到

发表于 2017-2-24 10:44:53 | 显示全部楼层 |阅读模式
  本文摘录自《Nodejs学习笔记》,更多章节及更新,请访问 github主页地址。欢迎加群交流,群号 197339705。


模块概览
  这个模块的重要性,基本不用强调了。在网络安全问题日益严峻的今天,网站采用HTTPS是个必然的趋势。
  在nodejs中,提供了 https 这个模块来完成 HTTPS 相关功能。从官方文档来看,跟 http 模块用法非常相似。
  本文主要包含两部分:


  • 通过客户端、服务端的例子,对https模块进行入门讲解。
  • 如何访问安全证书不受信任的网站。(以 12306 为例子)
  篇幅所限,本文无法对 HTTPS协议 及 相关技术体系 做过多讲解,有问题欢迎留言交流。

客户端例子
  跟http模块的用法非常像,只不过请求的地址是https协议的而已,代码如下:
var https = require('https');  

  
https.get('https://www.baidu.com', function(res){
  console.log('status code: ' + res.statusCode);
  console.log('headers: ' + res.headers);
  

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

服务端例子
  对外提供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);
  由于我并没有 www.chyingp.com 这个域名,于是先配置本地host
  

127.0.0.1 www.chyingp.com  

  启动服务,并在浏览器里访问 http://www.chyingp.com:3000。注意,浏览器会提示你证书不可靠,点击 信任并继续访问 就行了。

进阶例子:访问安全证书不受信任的网站
  这里以我们最喜爱的12306最为例子。当我们通过浏览器,访问12306的购票页面 https://kyfw.12306.cn/otn/regist/init 时,chrome会阻止我们访问,这是因为,12306的证书是自己颁发的,chrome无法确认他的安全性。
  对这种情况,可以有如下处理方式:


  • 停止访问:着急抢票回家过年的老乡表示无法接受。
  • 无视安全警告,继续访问:大部分情况下,浏览器是会放行的,不过安全提示还在。
  • 导入12306的CA根证书:浏览器乖乖就范,认为访问是安全的。(实际上还是有安全提示,因为12306用的签名算法安全级别不够)
例子:触发安全限制
  同样的,通过 node https client 发起请求,也会遇到同样问题。我们做下实验,代码如下:
var https = require('https');  

  
https.get('https://kyfw.12306.cn/otn/regist/init', function(res){   
  res.on('data', function(data){
  process.stdout.write(data);
  });
  
}).on('error', function(err){
  console.error(err);
  
});
  运行上面代码,得到下面的错误提示,意思是 安全证书不可靠,拒绝继续访问。
{ 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签名的证书还是不一样的。
  类似在浏览器里访问,我们可以采取如下处理:


  • 不建议:忽略安全警告,继续访问;
  • 建议:将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);
  
});

方法2:将12306的CA加入受信列表
  这里包含3个步骤:


  • 下载 12306 的CA证书
  • 将der格式的CA证书,转成pem格式
  • 修改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格式的。需要转换下格式才能用。关于 pem、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);
  
});

相关链接
  Why is my node.js SSL connection failing to connect?
  DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them
  Painless Self Signed Certificates in node.js
  利用OpenSSL创建自签名的SSL证书备忘(自建ca)
  OpenSSL 与 SSL 数字证书概念贴
  自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346542-1-1.html 上篇帖子: 使用nodejs防止csurf攻击的方法 下篇帖子: 图片访问实时处理的实现(nodejs和php)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表