今天学习express的中间件,看到了express的cookie-parser和express-session中间件,就对cookie和session好奇了,于是就花了时间研究它们,总结如下。
  由于HTTP协议是无状态的,即不会记录客户端与服务端的连接信息,但是随着互联网的发展,与用户的交互成了趋势,故需要一种机制来记录用户的信息,保持用户的状态,比如短时间内重复访问一个网站,可以让直接定位到用户最后一次浏览的位置,故cookie和session出现了。

cookie

  cookie是客户端请求服务器时,服务端记录的用户信息,存储在客户端,下一次客户端发送请求时会将cookie一起发送。当客户端访问web服务器时,服务器会记录用户的信息然后在响应信息的响应头中设置set-cookie头部,然后存储在客户端,下一次再请求web服务器时请求头中会加上cookie这一项并发送到服务器,服务器通过cookie判断用户是否访问过该网站。
  cookie是又时限的,有一个属性maxAge可以设置cookie的存储时间,超过时间后cookie会被删除,默认的是浏览器关闭时清除cookie。cookie一般用于用户的自动登录,记住密码等,将账户信息保存在cookie中,登录时cookie被传送到服务器完成自动登录。

express中设置set-cookie头

  服务器中生成cookie要存储在客户端时,服务端主要是设置set-cookie头,让它随响应信息response发送到客户端。那么服务器端设置set-cookie头的参数主要通过response.cookie(name,value[,options])设置,response.cookie是express中response对象设置cookie的方法:

  name:cookie的名字;value:规定 cookie 的值。这两者是必须得。

  options对象是用来设置set-cookie头部的选项:

  

ingress 从cookie 放header_客户端


  secure:true是一个推荐选项。 但是,它需要启用https的网站,即HTTPS是安全Cookie所必需的。 如果设置了安全性,通过HTTP访问站点时,cookie将不会被设置。

  以下面的图为例,第一次访问网站时,是响应头中有设置set-cookie,和响应信息一起发送到客户端:

ingress 从cookie 放header_客户端_02


  第二次再访问这个网站时,请求头中自动的加上了cookie,随着请求信息一起发送到服务器。

ingress 从cookie 放header_中间件_03

cookie-parser

  cookie的值value是一串字符或者是转化为json字符串的对象,cookie-parser是将cookie的值由字符串解析成对象的中间件,当使用cookie-parser中间件的时候,可以通过express中的request对象的cookies属性req.cookies查看cookies的值,比如req.cookies.name。req.cookies这个属性是一个对象,其包含了请求发送过来的cookies。如果请求没有带cookies,那么其值为{}。

session

  session和cookie的作用是一样的,也是存储用户信息,但是session是存储在服务器端的。session还需借助cookie将唯一标识sessionID存到客户端。当客户端访问web服务器时,会生成一个全局唯一标识sessionID,然后服务器会记录用户的信息然后存储到该session中,由于客户端下一次需要匹配sessionID,故需要将sessionID发送到客户端,方法有两种,一种就是设置set-cookie头将sessionID发送到客户端,另一种就是url重写。第二次请求该网站时,请求头中就会带上cookie,cookie的值是就是sessionID。session一般用于用户的身份验证,即利用sessionID判断用户是否合法。
  注意:session数据不会保存在cookie本身,只是sessionID。 session数据存储在服务器端。

express-session

  由于session的机制离不开cookie,故express-session中创建session时可以接收的options常见的有:cookie,name,resave,saveUninitialized,secret,store等具体可查看express-session。cookie是一个对象,里面的属性可以有maxAge、domain、expires、httpOnly、path等。

app.use(session({
        secret:'my app secret',// 用来对session id相关的cookie进行签名
        saveUninitialized:false,// 是否自动保存未初始化的会话,建议false
        resave:false,// 是否每次都重新保存会话,建议false
        store: new MongoStore({   //创建新的mongodb数据库存储session
            host: 'localhost',    //数据库的地址,本机的话就是127.0.0.1,也可以是网络主机
            port: 27017,          //数据库的端口号
            db: 'test-app'        //数据库的名称。
        }),
        name:'test',//cookie的name,默认值是:connect.sid
        cookie:{
            maxAge:10*1000
        }
    }));

  创建session后,可以在express的request对象的属性req.session对session进行操作,比如req.session.destroy方法可以销毁对话,req.session.save保存当前session,也可以通过req.session.id和req.sessionID查看session的id,但是只可读,不可写。也可用req.session.cookie查看cookie的各种属性,比如req.session.cookie.maxAge等,req.session还可以自定义属性,比如下面的例子中的req.session.views。

var express = require('express')
    var parseurl = require('parseurl')
    var session = require('express-session')
    
    var app = express()
    
    app.use(session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: true
    }))
    
    app.use(function (req, res, next) {
        var views = req.session.views
    
        if (!views) {
            views = req.session.views = {}
        }
    
        // get the url pathname
        var pathname = parseurl(req).pathname
    
        // count the views
        views[pathname] = (views[pathname] || 0) + 1
    
        next()
    })
    
    app.get('/foo', function (req, res, next) {
        res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
    })
    
    app.get('/bar', function (req, res, next) {
        res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
    })

cookie和session的区别

  1、最大的区别应该在于存储的地方不一样,cookie存储在客户端,session存储在服务器;
  2、从安全性方面来说,cookie存储在客户端,很容易被窃取,暴露用户信息,而session存储在服务器,被窃取的机会小很多,故session的安全性比cookie高;
  3、从性能方面来说,cookie存储在浏览器端消耗的是用户的资源,相对比较分散,而session消耗的服务器的内存,会造成服务器端的压力;
  4、cookie可以长期的存储在客户端,但是数量和大小都是有限制的;session存在服务器的时间较短,但是没有大小的限制。