Node学习入门篇(七):Connect自带的中间件

11人阅读 评论(0) 收藏 举报
分类:

本章内容

  • 解析cookie、请求主体和查询字符串的中间件
  • 实现Web程序核心功能的中间件
  • 处理Web程序安全的中间件
  • 提供静态文件服务的中间件

npm package: https://www.npmjs.com/package/package

解析cookie、请求主体和查询字符串的中间件

  • 常用中间件
    这里写图片描述

    这里写图片描述

注意:All node patches will be removed - all middleware should work without Connect and with similar frameworks like restify(connect内置中间件已经从connect中分离处理,使用时需要单独安装、引入)

  • 未签名cookie

1) install

npm install cookie-parser

2) 常规(未签名)cookie测试

var connect = require('connect');
var app = connect();
var cookieParser = require('cookie-parser')
app.use(cookieParser('sysuygm is cool'));
app.use(function(req, res) {
    console.log(req.cookies);
    console.log(req.signedCookies);
        "cookie":req.cookies,
        "signedCookies":req.signedCookies
        }));
});

3)客户端结果

发送

accept: application/json
accept-encoding: gzip, deflate
accept-language: en-US,en;q=0.8
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Authorization: Basic ZmFmYTpmYWZh
Cookie: foo=bar;bar=baz

收到

{
"cookie": {
"foo": "bar",
"bar": "baz",
"io": "GXHOFF8zxkVibldwAAAO"
},
"signedCookies": {}
}
  • 签名cookie

签名cookie更适合敏感数据,因为用它可以验证cookie数据的完整性,有助于防止中间人攻击。有效的签名cookie放在req.signedCookies对象中。把两个对象分开是为了体现开发者的意图。如果把签名的和未签名的cookie放到同一个对象中,常规cookie可能就会被改造,仿冒签名的cookie

签名cookie看起来像tobi.DDm3AcVxE9oneYnbmpqxoyhyKsk一样,点号(.)左边的是cookie的值,右边是在服务器上用SHA-1 HMAC生成的加密哈希值(基于哈希的消息认证码)。如果cookie的值或者HMAC被改变的话,Connect的解签会失败

1) 使用签名的cookie

cookieParser()中间件没有提供任何通过Set-Cookie响应头向HTTP客户端写出站cookie的功能。但Connect可以通过res.setHeader()函数写入多个Set-Cookie响应头

app.use(function(req, res) {
    console.log(req.cookies);
    // console.log(req.signedCookies);
    res.setHeader('Set-Cookie',
    'foo-bar;Expires=True,08 Jun 2021 10:18 GMT');
    res.end(JSON.stringify( {'seccuss':true}));
});

2) curl 查看

>curl http://localhost:3000/ -H "Cookie:foo-bar" --head
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: foo-bar;Expires=True,08 Jun 2021 10:18 GMT
Date: Sun, 15 Apr 2018 15:16:58 GMT
Connection: keep-alive

bodyParser():解析请求主体

  • 假设你要用HTML标签接受用户上传的文件。用一行代码添加bodyParser()中间件就全齐了
  • bodyParser()组件为你提供了req.body属性,可以用来解析JSON、x-www-form-urlencoded和multipart/form-data请求
  • 如果是multipart/form-data请求,比如文件上传,则还有req.files 对象
  • 这是个非常有用的组件,实际上它整合了其他三个更小的组件:json(), urlencoded(), 和multipart()

1) 先安装

npm install body-parser

2) 使用

var cookieParser = require('cookie-parser')
// app.use(bodyParser()); 最好是像下面那样显示指定子组件,否则会提示冗余

// parse application/x-www-form-urlencoded
 app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
 app.use(bodyParser.json());

app.use(function(req, res) {
    console.log(req.body.username);
    // console.log(req.signedCookies);
    res.end(JSON.stringify( {
        'username':req.username,
        'password':req.pass
    }));
});

POST数据

{
  "username": "caicai",
  "pass":"sysuygm"
}

如果bodyParser()在内存中缓存json和x-www-form-urlencoded请求主体,产生一个大字符串,那攻击者会不会做一个超级大的JSON请求主体对服务器做拒绝服务攻击呢?答案基本上是肯定的,所以Connect提供了limit()中间件组件。

limit():请求主体的限制

  • limit()中间件组件的目的是帮助过滤巨型的请求
  • 防止脚本攻击
    (好像已经被丢弃了)

query():查询字符串解析

  • 它解析查询字符串,为程序提供req.query对象
  • 它会将请求发送过来的查询字符串以JSON格式作为响应返回去
    (似乎已经被废弃?)

favicon():提供favicon

(似乎已经被废弃?)
使用 serve-favicon代替,用static-favicon会提示:

(node:3324) 
DeprecationWarning: static-icon deprecated; switch to module serve-favicon

使用firefox才能看到favicon!

::1 - - [Sun, 15 Apr 2018 16:55:37 GMT] "GET / HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
undefined
::1 - - [Sun, 15 Apr 2018 16:59:42 GMT] "GET / HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"
undefined
::1 - - [Sun, 15 Apr 2018 16:59:54 GMT] "GET / HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"

logger():记录请求

已被废弃,现在用morgan代替, 直接安装morgan

body-parser deprecated bodyParser: use individual json/urlencoded middlewares connect.js:27:9
body-parser deprecated undefined extended: provide extended option ..\node_modules\body-parser\index.js:105:29
morgan deprecated undefined format: specify a format connect.js:30:9
morgan deprecated default format: use combined format connect.js:30:9
listening...
undefined
::1 - fafa [Sun, 15 Apr 2018 16:48:14 GMT] "POST /?username=pppp HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

vhost():虚拟主机

  • vhost()(虚拟主机)中间件是一种通过请求头Host路由请求的简单、轻量的办法
  • 这项任务通常是由反向代理完成的,可以把请求转发到运行在不同端口上的本地服务器那里
  • vhost()组件在同一个Node进程中完成这一操作,它将控制权交给跟vhost实例关联的Node HTTP服务器
  • 可使子域名在Express中更容易管理。
  • 缺点:如果一个网站引发了崩溃,你的所有网站都会宕掉(因为它们都运行在同一个进程中)

session():会话管理

需要安装 session-parser,且在cookie-parser前引入。


安全相关部分

basicAuth():HTTP基本认证

  • 基本认证是非常简单的HTTP认证机制,并且在使用时应该小心,因为如果不是通过HTTPS进行认证,用户凭证很可能会被攻击者截获

  • basicAuth()在最新的connect中已无法使用,且无法单独使用,似乎只有Express中才能使用。

app.use(basicAuth(connect.basicAuth(auth)));
                          ^

TypeError: connect.basicAuth is not a function
    at Object.<anonymous> (F:\后台开发\wechat\lib\connect.js:30:27)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

csrf():跨站请求伪造防护

  • 跨站请求伪造(CSRF)利用站点对浏览器的信任漏洞进行攻击
  • csrf()会生成一个包含24个字符的唯一ID,认证令牌,作为req.session._csrf附到用户的会话上
  • 这个令牌会作为隐藏的输入控件_csrf出现在表单中,CSRF在提交时会验证这个令牌
>npm install csrf

使用:
为了确保csrf()可以访问req.body._csrf(隐藏输入控件的值)和req.session._csrf,你要确保csrf()添加在了bodyParser()和session()的下面

app.use(favicon(__dirname + '/timg.ico'));
// app.use(basicAuth(connect.basicAuth(auth)));
app.use(cookieParser('private-key'));
app.use(session({
    keys:['aaa','bbb','ccc'],
    maxAge:360000*24,
    name:'session'
}));
app.use(bodyParser());
//添加在bodyParser()和session()的下面
app.use(csrf());
app.use(morgan());

errorHandler():开发错误处理

  • 可以基于请求头域Accept提供详尽的HTML、JSON和普通文本错误响应
  • errorHandler()是要用在开发过程中的,不应该出现在生产环境中

安装:

npm install errorhandler

example:

var connect = require('connect')
var errorhandler = require('errorhandler')

var app = connect()

if (process.env.NODE_ENV === 'development') {
  // only use in development 
  app.use(errorhandler())
}

static():静态文件服务

  • static()中间件实现了一个高性能的、灵活的、功能丰富的静态文件服务器,支持HTTP缓存机制、范围请
  • 有对恶意路径的安全检查,默认不允许访问隐藏文件(文件名以.开头),会拒绝有害的null字节
  • static()本质上是一个非常安全的、完全能胜任的静态文件服务中间件,可以保证跟目前各种HTTP客户端的兼容
  • 假定你的程序遵循典型的场景,要返回./public目录下的静态资源文件

compress():压缩静态文件

directory():目录列表

查看评论

组合语言之艺术9 the end

附录三    键盘输入码表┌───┬───┬───┬───┬───┐│键  位│常  态│高  位│控制态│变更态││ KEY  │NORMAL│SHIFT │ CTRL │ ALT  │├───┼─...
  • dot99
  • dot99
  • 2001-08-04 22:34:00
  • 777

关于node--parser【解析中间件】问题全解

小爷我也是醉了。。。本来是畅通快意,一路无阻,西天大道,畅意无限~~ 遇到parser error 《》》《《《》《》《》《《《《》《《》》《》》》》《》》《》《》《《《》《》...
  • qq_35085956
  • qq_35085956
  • 2017-03-13 14:27:41
  • 598

Node中的Connect——常用中间件

接下来介绍一个Connect内置的一些中间件: static中间件   1.挂载   static允许将任意一个URL匹配到文件系统中任意一个目录。如:将/my-images URL和名为/...
  • qq_15096707
  • qq_15096707
  • 2016-12-17 22:50:54
  • 882

Node Connect 及其中间件的理念相当好

好到有种相见恨晚的感觉,呵呵。Connect 所谓的中间件思想,可谓不新鲜。但是于 Node 上面使用,却是第一个吃螃蟹的人,以致今日,有为数不少的第三方中间件。套一句俗话,充分利用好这些中间件,能让...
  • zhangxin09
  • zhangxin09
  • 2014-01-15 18:56:41
  • 6279

Node 学习之Connect模块及其中间件的使用

Node Connect模块 中间件 static中间件 bodyParser中间件 looger中间件
  • ganyingxie123456
  • ganyingxie123456
  • 2017-06-13 12:35:56
  • 309

NodeJS Connect 简单错误处理中间件

NodeJS Connect 简单错误处理中间件 //错误处理中间件函数必须接受四个参数:err、req、res和next, //而常规的中间件只有三个参数:req、res和next fun...
  • xuexueenen
  • xuexueenen
  • 2016-02-11 15:46:16
  • 982

Connect中间件示例

server.js var connect = require('connect'); var app = connect(); app.listen(3000); app.use(logger) ...
  • anhuizhuanjiao
  • anhuizhuanjiao
  • 2016-03-13 21:19:40
  • 711

理解Node.js中间件以及Connect 模块

本文链接地址: 理解Node.js中间件以及Connect 模块 刚开始学习Express的时候,在app.js中发现app.use,当时比较困惑。 1 app.use(express....
  • shmnh
  • shmnh
  • 2015-03-28 00:46:28
  • 612

NodeJS Connect 简单路由中间件

NodeJS 简单路由中间件//使用URL中的parse方法 var parse = require("url").parse; //这里只接受一个参数,就是routes对象 module.expor...
  • xuexueenen
  • xuexueenen
  • 2016-02-11 15:15:04
  • 757

Node学习入门篇(六):Connect

内容 搭建一个Connect程序 Connect中间件的工作机制 为什么中间件的顺序很重要 挂载中间件和服务器创建可配置的中间件 使用错误处理中间件 ...
  • w_bu_neng_ku
  • w_bu_neng_ku
  • 2018-04-15 16:45:52
  • 9