Cookie和Session在Node.JS中的实践(一)
Cookie和Session是一个非常有趣的概念,也是一个老生常谈的话题。然而,作者看了许多文章,也翻看了几本书籍,它们对Cookie和Session的概念、机制的描述都各不一致,大多文章都只谈到了Cookie和Session其中之一,但在现实开发中两者都需要使用。作者有时候写程序用到了两者但有时候连自己都没理解他们之间的区别、联系、机制等等概念。
Cookie
HTTP的无状态协议是产生Cookie技术的重要原因
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信转台进行保存。也就是说HTTP是不会做持久化(Persistence)处理的。当使用HTTP进行通信时,每当有新的请求发送,就会有对应的新响应产生。这并不是缺陷,而是HTTP为了更快的处理大量事务。
然而,无状态协议让业务处理变得困难的情况越来越多了,如:我们登录了某宝,就算我们跳转到了某宝的其他页面,也需要保持登录这个“状态”,但HTTP协议做不到。针对这个例子,网站为了掌握是谁发送的请求,就需要把用户的状态保存起来。
为了实现期望的保持状态功能,于是引入了Cookie技术,所以cookie的主要作用就是记录状态,包括会话状态管理,用户的个性化设置,浏览器的行为跟踪。有了Cookie再用HTTP通信就可以管理状态,因此就有人说Cookie是HTTP的扩展。
客户端中的Cookie
Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
这是我们经常听到的关于Cookie的概念,但从来没见过Cookie长什么样子。在Chrome中通过开发者工具可以查看网站用到的所有Cookie,以博客园用到的Cookie为例。
另外我们可以使用JavaScript
原生的API获取cookie:document.cookie
,使用该方法获只能获取非HttpOnly
类型的cookie。
跟直接在chrome
查看cookie
,使用控制台Console得到的结果除了HttpOnly
以外的Cookie都是一样的。可以发现,每一个cookie
都有几个不同的字段:name,value,domain,path,expires/max-age,HttpOnly,secure
来分析一下比较常用的字段:
name和value
设置cookie
的名字和值。必须设置字段。
domain和path
domain
是域名,path
是路径,两者加起来就是URL,domain
结合path
一起来限制cookie能被哪些URL访问。概念比较抽象,举个例子
以博客园为例,博客园cookie的
domain
为"cnblogs.com",path
为"/",若我们请求的URL的域名是"cnblogs.com"或者它的子域"home.cnblogs.com",并且URL的路径都是"/"或者它的子路径"/example","/home/user",以上这些URL都能访问cookie,浏览器会将这些cookie添加到请求的cookie头部中去。
以上两个字段是可选的,domain
默认cookie所在的域名,path
默认设置该cookie的网页所在的目录。
secure
带有此字段的cookie表示只有在请求使用HTTPS协议的时候才能被传到服务器中。但通常建议不会把保密的数据放到cookie中存储。
HttpOnly
JavaScript原生API能访问浏览器的cookie,这可能会遭遇XSS
攻击,为了防范,设置了该字段的cookie,原生API是无法访问的。
expire和Max-age
expires
:表示cookie的最长有效时间,cookie失效时刻=expires形式是符合HTTP-date
规范的时间戳,这个Date
是一个通用的首部,语法:Date: <day-name> <day> <month> <year> <hour>:<minute>:<second> GMT
,可以通过new Date().toGMTString获得
。
Max-Age
:表示cookie存储的最长时间。单位是秒,有效期:创建时刻+max-age
。跟expire的作用的一样的,若两者都存在则Max-Age
的优先级高。该属性在一些老浏览器中不支持。
如果没有给cookie设置以上这两个字段,那么cookie默认就是所谓的会话Cookie
,有效期就是session
,这里的session指的就是会话,浏览器关闭后cookie就没有了整个过程就是一个会话。
HTTP+COOKIE工作原理
HTTP是无状态协议,所以需要COOKIE技术来保持状态。我们知道,Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,这里分析一下HTTP+COOKIE的工作原理:
考虑两种可能:
1.客户端第一请求该台服务器,也就是服务器没有发送cookie给该台客户端,因此客户端的第一次请求是没有cookie首部字段数据的,而服务器作为响应也会将cookie首部数据发送到该台客户端中。
2.客户端不是第一次请求该台服务器,服务器已经有发送过cookie给该台客户端,那么在客户端上的cookie都会随着请求一同发送到服务器中,而服务器会检查这个cookie给你返回相应的数据,而不再需要设定cookie。
COOKIE实践
为了能明白上面的cookie工作原理,以下进行实践,建议读者跟我一起做
1.还是以博客园为例,在账户退出的状态下打开(https://www.cnblogs.com)[博客园首页],使用Chrome,如果对浏览器开发工具比较熟悉也可以使用火狐,把网站以往的cookie清除
2.进行刷新页面,再打开chrome开发工具network
,选择其中的请求,点击查看请求首部(Request Header)
以及响应首部(Response Header)
,发现响应首部有set-cookie字段
,即服务器给浏览器设置的cookie。并且,请求首部是没有cookie字段的,因为我们自己清除了cookie!
此时,再去查看Cookie面板发现服务器已经给浏览器设置了Cookie。
再次刷新页面。自行重复以上步骤,发现请求首部多了一个cookie
字段,即有了cookie后,对服务器的每一次请求都会带上cookie。
总结
HTTP的无状态协议是产生Cookie技术的重要原因,cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。cookie的主要作用就是记录状态,包括会话状态管理,用户的个性化设置,浏览器的行为跟踪。
写到这,已经涉及不少知识,文章篇幅太长不好,第二篇再写session以及在node.JS的实践。剧透一下,通过Node.JS操作cookie的代码:)
const express = require('express');
const cookieParser = require('cookie-parser')
var server = express();
server.use(cookieParser('alkdukajvldfq'));
server.use('/', function(req, res) {
// 发送cookie,path是指定能访问cookie的路径,可从下往上读取,反则不行,比如/=>path:/aaa
res.cookie('name', 'janro', {path: '/', maxAge: 3600*1000, signed: true});
// 读取cookie
console.log(req.cookies);
console.log(req.signedCookies);
// / 和favicon
console.log(req.url);
res.send('OK');
//清除cookie
res.clearCookie('name');
});
server.listen(8080);
下次,session见。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
Reference
- https://segmentfault.com/a/1190000004556040
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
- https://segmentfault.com/a/1190000007579928
- 图解HTTP
- JavaScript高级程序设计
Cookie和Session在Node.JS中的实践(一)的更多相关文章
- Cookie和Session在Node.JS中的实践(三)
Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...
- Cookie和Session在Node.JS中的实践(二)
Cookie和Session在Node.JS中的实践(二) cookie篇在作者的上一篇文章Cookie和Session在Node.JS中的实践(一)已经是写得算是比较详细了,有兴趣可以翻看,这篇是s ...
- Node.js中的Session,不要觉得简单哦。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...
- 在node.js中使用COOKIE
node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...
- Node.js中的不安全跳转如何防御详解
Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的 ...
- 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...
- 如何在Node.js中合并两个复杂对象
通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...
- Node.js 中MongoDB的基本接口操作
Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...
- 初步揭秘node.js中的事件
当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...
随机推荐
- day06_02 元组
1.0 元组 元组被称为只读列表,即数据可以被查询,但不能被修改,所以,列表的切片操作同样适用于元组.元素卸载小括号(())里,元素之间用逗号隔开. tup1 = () #空元组 tup2 = (20 ...
- 【多线程学习(1)】创建java多线程
1)java多线程的创建方式有三种: 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 第一种: //继承Thread类 class ExtendsThread ex ...
- BI商业智能培训系列——(二)SSIS入门
简介: SSIS,Microsoft SQL Server Integration Services.Integration意为"整合"."一体化".上篇博客中 ...
- 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分+贪心
题目描述 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径. ...
- task [最大权闭合子图]
题面 思路 其实仔细读透就发现,是一个最大权闭合子图的模型 套进网络流里面就挺好做的了 可以选择重载这道题里面的一些运算(加减,取最小值),这样比较方便 Code #include<iostre ...
- 洛谷 P2173 [ZJOI2012]网络 解题报告
P2173 [ZJOI2012]网络 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环, ...
- mac 安装 visual studio 配置
前言:今天主要分享的是 Mac 下一款编程软件--Visual Studio,的确,这款软件之前一直是只有 Windows 系统独占的,2017年终于开发了 Mac 版本. 微软这次为 Mac 开发者 ...
- 为Ubuntu Gnome环境创建桌面快捷方式
为Ubuntu Gnome环境创建桌面快捷方式 安装gnome-panel包 sudo apt-get install --no-install-recommends gnome-panel 启动终端 ...
- bzoj4418 [Shoi2013]扇形面积并
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4418 [题解] 被题目名称吓死系列. 用一棵线段树维护当前有哪些半径. 那么将扇形差分,每段 ...
- 行为型设计模式之迭代器模式(Iterator)
结构 意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示. 适用性 访问一个聚合对象的内容而无需暴露它的内部表示. 支持对聚合对象的多种遍历. 为遍历不同的聚合结构提供一 ...