why Cookie and Session
我们为什么要引入Cookie和Session?因为HTTP是一个无状态的连接协议,为了支持客户端与服务器之间的交互,我们就需要通过不同的技术来交互存储状态,而这些不同的技术就是Cookie和Session.
通俗来说,客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,把用户的状态数据关联起来就显得重要了。比如当我们在博客项目的某个页面进行了登录操作,那么当你跳转到 创建博客页面 浏览器是怎么判断你已经登录呢?这都需要用到Cookie和Session
express 中的Cookie###
req.cookies
因为 cookie 的格式为 name = value 格式
,当cookie:name=yujuan ,req.cookies.name可以获取name对应的值,即
// cookie: name=yujuan
req.cookies.name
// => "yujuan"
res.cookie(name, value, [options])
设置cookie name值为value
,[options]
表示可选参数,其他可选的 cookie 参数会影响将 cookie 发送给服务器端的过程,主要有以下几种:
- path:表示 cookie 影响到的路径,匹配该路径才发送这个 cookie。path 属性默认为 "/".
- expires 和 maxAge:告诉浏览器这个 cookie 什么时候过期,expires 是 UTC 格式时间,maxAge (单位是毫秒)是 cookie 多久后过期的相对时间。当不设置这两个选项时,会产生 session cookie,意味着当用户关闭浏览器时,cookie就被清除。一般用来保存 session 的 session_id。
- secure:当 secure 值为 true 时,前提是HTTPS 连接成功,这样浏览器和服务器就能加密传输数据——cookie 在 HTTPS 中有效,在 HTTP 中是无效。
- httpOnly:浏览器不允许脚本操作 document.cookie 去更改 cookie。一般情况下都应该设置这个为 true,这样可以避免被 xss 攻击拿到 cookie。
详细用法可看官网http://expressjs.jser.us/3x_zh-cn/api.html#res.cookie
看看在express中cookie的用法#####
// 首先引入 cookie-parser 这个模块
var cookieParser = require('cookie-parser');
// 使用 cookieParser 中间件,cookieParser(secret, options)
// options 传入上面介绍的 cookie 可选参数
app.use(cookieParser());
app.get('/', function (req, res) {
// 如果请求中的 cookie 存在 isVisit, 则输出 cookie
// 否则,设置 cookie 字段 isVisit, 并设置过期时间为1分钟
if (req.cookies.isVisit) {
console.log(req.cookies);
res.send("再次欢迎访问");
} else {
res.cookie('isVisit', 1, {maxAge: 60 * 1000});
res.send("欢迎第一次访问");
}
});
express 中的Session###
cookie 虽然很方便,但是使用 cookie 有一个很大的弊端,cookie 中的所有数据在客户端就可以被修改,数据非常容易被伪造,那么一些重要的数据就不能存放在 cookie 中了,而且如果 cookie 中数据字段太多会影响传输效率。为了解决这些问题,就产生了 session,session 中的数据是保留在服务器端的
session 可以存放在 1)内存、2)cookie本身、3)redis 或 memcached 等缓存中 4)数据库中 . 放在数据库比前面三种查询速度慢,可是对什么时候会删除不太懂,是不是手动删除整张表呢——求解答哈哈
下面的实例代码session是存放在数据库的:
app.post('/check-login', (req, res, next)=> {
User.findOne({username: req.body.username}, (err, doc)=> {
if (err) {
return (next(err));
}
if (!doc) {
res.status(500).send({err: "该用户不存在"});
}
else {
if (req.body.password === doc.password) {
var randomId = uuid.v4();
new Session({
username: req.body.username,
password: req.body.password,
randomId: randomId
}).save((err, doc)=> {
res.cookie('user', randomId, {path: '/'});
res.status(200).send({data: doc.username});
})
} else {
res.status(500).send({err: "输入密码有误"});
}
}
})
});
登录时发送用户名username和密码password的验证请求,验证通过则产生随机数randomId (一个 128比特的数字),将randomId,username,password数据保存到本地数据库的Session表中,并设置cookie user的值为randomId
接下来,说说express中Session的用处就是能根据自己设定的随机数randomId ,当请求到来时,服务端检查 cookie 中保存的 randomId 并通过这个 randomId 与本地数据库存储的Session表的数据关联起来,进行数据的获取,比如对用户名信息的获取,代码如下:
app.get('/verify-user-indentity',(req, res, next)=> {
if (req.cookies.user) {
Session.findOne({randomId: req.cookies.user}, (err, doc)=> {
if (err) {
return (next(err));
}
if (!doc) {
res.status(500).send({err: "该用户不存在"});
} else {
res.status(200).send(doc.username);
}
})
} else {
res.status(403).send('');
}
});
这样做的好处是,当我们下次访问时,因为设置过 cookie user的值为randomId. 所以cookie 会带有这个字符串,然后浏览器就知道你是上次访问过的某某某,然后从服务器的存储中取出上次记录在你身上的数据。由于字符串是随机产生的,而且位数足够多,所以也不担心有人能够伪造。
好了,就到这里。
每天都努力一点
谢谢你看完