Nodejs进阶:核心模块https 之 如何优雅的访问12306

本文摘录自《Nodejs学习笔记》,更多章节及更新,请访问 github主页地址。欢迎加群交流,群号 197339705

模块概览

这个模块的重要性,基本不用强调了。在网络安全问题日益严峻的今天,网站采用HTTPS是个必然的趋势。

在nodejs中,提供了 https 这个模块来完成 HTTPS 相关功能。从官方文档来看,跟 http 模块用法非常相似。

本文主要包含两部分:

  1. 通过客户端、服务端的例子,对https模块进行入门讲解。
  2. 如何访问安全证书不受信任的网站。(以 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无法确认他的安全性。

对这种情况,可以有如下处理方式:

  1. 停止访问:着急抢票回家过年的老乡表示无法接受。
  2. 无视安全警告,继续访问:大部分情况下,浏览器是会放行的,不过安全提示还在。
  3. 导入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签名的证书还是不一样的。

类似在浏览器里访问,我们可以采取如下处理:

  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);
});

方法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格式的。需要转换下格式才能用。关于 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 证书类型 证书扩展名

时间: 2024-10-30 07:35:11

Nodejs进阶:核心模块https 之 如何优雅的访问12306的相关文章

Nodejs进阶:核心模块net入门与实例讲解

本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址. 模块概览 net模块是同样是nodejs的核心模块.在http模块概览里提到,http.Server继承了net.Server,此外,http客户端与http服务端的通信均依赖于socket(net.Socket).也就是说,做node服务端编程,net基本是绕不开的一个模块. 从组成来看,net模块主要包含两部分,了解socket编程的同学应该比较熟悉了: net.Server:TCP server,内部通过

Nodejs进阶:核心模块net入门学习与实例讲解_node.js

模块概览 net模块是同样是nodejs的核心模块.在http模块概览里提到,http.Server继承了net.Server,此外,http客户端与http服务端的通信均依赖于socket(net.Socket).也就是说,做node服务端编程,net基本是绕不开的一个模块. 从组成来看,net模块主要包含两部分,了解socket编程的同学应该比较熟悉了: net.Server:TCP server,内部通过socket来实现与客户端的通信. net.Socket:tcp/本地 socket的

Nodejs进阶:核心模块Buffer常用API使用总结

本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. 模块概览 Buffer是node的核心模块,开发者可以利用它来处理二进制数据,比如文件流的读写.网络请求数据的处理等. Buffer的API非常多,本文仅挑选 比较常用/容易理解 的API进行讲解,包括Buffer实例的创建.比较.连接.拷贝.查找.遍历.类型转换.截取.编码转换等. 创建 new Buffer(array) Buffer.alloc(length) Bu

nodejs的require模块(文件模块/核心模块)及路径介绍_基础知识

在nodejs中,模块大概可以分为核心模块和文件模块. 核心模块是被编译成二进制代码,引用的时候只需require表示符即可,如(require('net')). 文件模块,则是指js文件.json文件或者是.node文件.在引用文件模块的时候后要加上文件的路径:/.../.../xxx.js表示绝对路径../xxx.js表示相对路径(同一文件夹下的xxx.js),../表示上一级目录.如果既不加/.../.../又不加./的话,则该模块要么是核心模块,要么是从一个node_modules文件夹

NodeJS中的模块是单例的吗?

本文翻译自 Lazlojuly 的 are-node-js-modules-singletons. 本文从属于笔者的NodeJS入门与最佳实践中的NodeJS 基础系列文章,包括NodeJS 入门.NodeJS 模块导出与解析.NodeJS IOStream.NodeJS HTTPS这几部分. 笔者之前在使用require导入模块时,特别是在导入有状态的模块时,笔者会考虑其是否在多次导入情况下依然保持单例特性,或者说对于同一个文件在不同路径下导入时,是否能够识别为一致?本文即是对该特性进行解析.

我国物联网星座核心模块开展在轨验证

2017年11月15日,北京国电高科科技有限公司研制的UHF频段DCS(Data Collecting System)载荷模块在太原发射场搭载CZ-4C运载火箭发射入轨,开展在轨试验,本次试验任务对公司全球物联网星座布局具有重要意义. DCS载荷是开展物联网星座应用的核心模块,其本质上是一种天基短报文通信系统,用于接收分散于全球的各类终端上行数据,存储并转发至地面数据中心,还可提供下行业务信息广播,进而实现对地面终端管控. DCS载荷入轨后,经过必要检测,将开展多项试验,包括: 1.天地接口对接

项目管理如何把核心模块隔离

问题描述 项目管理如何把核心模块隔离 项目管理如何将核心层隔离,分层开发代码SVN同步核心层不暴露源代码?如何解决 解决方案 要看你用的语言和开发工具了,把核心模块编译成可执行的库/包,让外层能调用就可以了. 解决方案二: 核心层编译好之后,再供调用

《深入理解Nginx:模块开发与架构解析》一2.4 用HTTP核心模块配置一个静态Web服务器

2.4 用HTTP核心模块配置一个静态Web服务器 静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现,当然,一个完整的静态Web服务器还有许多功能是由其他的HTTP模块实现的.本节主要讨论如何配置一个包含基本功能的静态Web服务器,文中会完整地说明ngx_http_core_module模块提供的配置项及变量的用法,但不会过多说明其他HTTP模块的配置项.在阅读完本节内容后,读者应当可以通过简单的查询相关模块(如ngx_http_gzip_f

Hadoop2源码分析-HDFS核心模块分析

1.概述 这篇博客接着<Hadoop2源码分析-RPC机制初识> 来讲述,前面我们对MapReduce.序列化.RPC进行了分析和探索,对Hadoop V2的这些模块都有了大致的了解,通过对这些模块的研究,我们明白了MapReduce的运行流程以及内部的实现机制,Hadoop的序列化以及它的通信 机制(RPC).今天我们来研究另一个核心的模块,那就是Hadoop的分布式文件存储系统--HDFS,下面是今天分享的内容目录: HDFS简述 NameNode DataNode 接下来,我们开始今天的