express之cookie和session
今天学习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头部的选项:
secure:true是一个推荐选项。 但是,它需要启用https的网站,即HTTPS是安全Cookie所必需的。 如果设置了安全性,通过HTTP访问站点时,cookie将不会被设置。
以下面的图为例,第一次访问网站时,是响应头中有设置set-cookie,和响应信息一起发送到客户端:
第二次再访问这个网站时,请求头中自动的加上了cookie,随着请求信息一起发送到服务器。
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存在服务器的时间较短,但是没有大小的限制。