nodeJS之Cookie和Session(一)
nodeJS之Cookie和Session(一)
一:Cookie
HTTP是一个无状态协议,客户端每次发出请求时候,下一次请求得不到上一次请求的数据,那么如何将上一次请求和下一次请求的数据关联起来呢?
比如登录官网后,再切换到其他页面时候,那么其他的页面是如何知道该用户已经登录了呢?所以这就可以使用到cookie中的值来判断了。
cookie它是一个由浏览器和服务器共同协作实现的协议的。那么cookie分为如下几步实现:
1. 服务器端向客户端发送cookie。
2. 浏览器将cookie保存。
3. 之后每次请求都会将cookie发向服务器端。
1.1 服务器端发送cookie
服务器发送cookie给客户端是通过HTTP响应报文实现的。在set-Cookie中设置给客户端发送的cookie,cookie格式如下:
Set-Cookie: name=value; Max-Age=60; Path=/; domain=.domain.com;Expires=Sun, 27 May 2018 05:44:24 GMT; HttpOnly, secure;
如下图所示

其中name=value是必选项,其他都是可选的,cookie主要构成如下:
name: 一个唯一确定cookie的名称。
value: 存储在cookie中字符串的值。
domain: cookie对于那个域下是有效的,
path: 表示这个cookie影响到的路径,浏览器会根据这个配置,向指定的域中匹配的路径发送cookie。
expires: 失效时间,表示cookie何时失效的时间,如果不设置这个时间,浏览器就会在页面关闭时将删除所有的cookie,不过我们也可以自己设置过期时间。
注意:如果客户端和服务器端设置的时间不一致,使用expires就会存在偏差。
max-age: 用来告诉浏览器此cookie多久过期(单位是秒),一般的情况下,max-age的优先级高于expires。
HttpOnly: 告诉浏览器不允许通过脚本document.cookie去更改值,这个值在document.cookie中也是不可见的,但是在http请求会携带这个cookie,
注意:这个值虽然在脚本中使不可取的,但是在浏览器安装目录中是以文件形式存在的,这个设置一般在服务器端设置的。
secure:安全标志,指定后,当secure为true时候,在HTTP中是无效的,在HTTPS中才有效,表示创建的cookie只能在HTTPS连接中被浏览器传递到服务器端进行会话验证,如果是HTTP连接则不会传递该信息,所以一般不会被且听到。
服务器端设置cookie代码如下:
const express = require('express');
const app = express();
app.listen(3001, () => {
console.log('port listen 3001');
});
app.get('/', (req, res) => {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', 'isVisit=1;domain=/;path=/;max-age=60*1000');
res.send('欢迎你~');
});
直接设置Set-Cookie过于原始,我们可以对cookie的设置过程做如下封装;
const express = require('express');
const app = express();
app.listen(3001, () => {
console.log('port listen 3001');
});
const serilize = function(name, value, options) {
if (!name) {
throw new Errpr('cookie must have name');
}
var rets = [];
value = (value !== null && value !== undefined) ? value.toString() : '';
options = options || {};
rets.push(encodeURIComponent(name) + "=" +encodeURIComponent(value));
if (options.domain) {
rets.push('domain=' + options.domain);
}
if (options.path) {
rets.push('path=' + options.path);
}
if (options.expires) {
rets.push('expires=' + options.expires.toGMTString());
}
if (options.maxAge && typeof options.maxAge === 'number') {
rets.push('max-age=' + options.maxAge);
}
if (options.httpOnly) {
rets.push('HTTPOnly');
}
if (options.secure) {
rets.push('secure');
}
return rets.join(';');
};
app.get('/', (req, res) => {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', serilize('isVisit', '1'));
res.send('欢迎你~');
});
1.2 服务器端解析cookie
cookie可以设置不同的域和路径,所以对于同一个name value,在不同的域不同的路径下是可以重复的,浏览器会按照与当前请求的url或页面地址最佳匹配的顺序来排定先后顺序。
服务器端解析代码如下:
const parse = function(str) {
if (!str) {
return;
}
const dec = decodeURIComponent;
var cookies = {};
const rets = str.split(/\s*;\s*/g);
rets.forEach((r) => {
const pos = r.indexOf('=');
const name = pos > -1 ? dec(r.substr(0, pos)) : r;
const val = pos > -1 ? dec(r.substr(pos + 1)) : null;
// 只需要拿到最匹配的那个
if (!cookies.hasOwnProperty(name)) {
cookies[name] = val;
}
});
return cookies;
};
因此整个代码如下:
const express = require('express');
const app = express();
app.listen(3001, () => {
console.log('port listen 3001');
});
const serilize = function(name, value, options) {
if (!name) {
throw new Errpr('cookie must have name');
}
var rets = [];
value = (value !== null && value !== undefined) ? value.toString() : '';
options = options || {};
rets.push(encodeURIComponent(name) + "=" +encodeURIComponent(value));
if (options.domain) {
rets.push('domain=' + options.domain);
}
if (options.path) {
rets.push('path=' + options.path);
}
if (options.expires) {
rets.push('expires=' + options.expires.toGMTString());
}
if (options.maxAge && typeof options.maxAge === 'number') {
rets.push('max-age=' + options.maxAge);
}
if (options.httpOnly) {
rets.push('HTTPOnly');
}
if (options.secure) {
rets.push('secure');
}
return rets.join(';');
};
const parse = function(str) {
if (!str) {
return;
}
const dec = decodeURIComponent;
var cookies = {};
const rets = str.split(/\s*;\s*/g);
rets.forEach((r) => {
const pos = r.indexOf('=');
const name = pos > -1 ? dec(r.substr(0, pos)) : r;
const val = pos > -1 ? dec(r.substr(pos + 1)) : null;
// 只需要拿到最匹配的那个
if (!cookies.hasOwnProperty(name)) {
cookies[name] = val;
}
});
return cookies;
};
app.get('/', (req, res) => {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', serilize('isVisit', '1'));
res.send('欢迎你~');
console.log(parse('isVisit=1'));
});
在命令行中运行后可以看到打印出cookie信息键值对,如下:

1.3 express中的cookie
express4中操作的cookie使用 cookie-parser模块;如下代码使用:
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.listen(3000, () => {
console.log('port listen 3000');
});
app.use(cookieParser());
app.get('/', (req, res) => {
if (req.cookies.isVisit) {
console.log(req.cookies);
res.send('再次欢迎你');
} else {
// cookie设置过期时间为10分钟
res.cookie('isVisit', 1, {maxAge: 60*1000});
res.send('欢迎你~');
}
});
二:session
cookie操作很方便,但是使用cookie安全性不高,cookie中的所有数据在客户端就可以被修改,数据很容易被伪造;所以一些重要的数据就不能放在cookie当中了,并且cookie还有一个缺点就是不能存放太多的数据,为了解决这些问题,session就产生了,session中的数据保留在服务端的。
2.1 基于Cookie来实现用户和数据的映射
把数据放到cookie中是不可取的,但是我们可以将口令放在cookie中的,比如cookie中常见的会放入一个sessionId,该sessionId会与服务器端之间会产生
映射关系,如果sessionId被篡改的话,那么它就不会与服务器端数据之间产生映射,因此安全性就更好,并且session的有效期一般比较短,一般都是设置是
20分钟,如果在20分钟内客户端与服务端没有产生交互,服务端就会将数据删除。
session的原理是通过一个sessionid来进行的,sessionid是放在客户端的cookie中,当请求到来时候,服务端会检查cookie中保存的sessionid是否有,
并且与服务端的session data映射起来,进行数据的保存和修改,也就是说当我们浏览一个网页时候,服务端会随机生成一个1024比特长的字符串,然后存在
cookie中的sessionid字段中,当我们下次访问时,cookie会带有sessionid这个字段。
express 中 express-session模块
在express中操作session可以使用 express-session这个模块,主要方法是session(options),options中包含可选的参数有:
name: 保存session的字段名称。默认为 connect.sid
store: session的存储方式,默认存放在内存中。
secret: 通过设置secret字符串,来计算hash值并放在cookie中,使产生的signedCookie防篡改。
cookie: 设置存放session id的cookie的相关选项,默认为 (default: { path: '/', httpOnly: true, secure: false, maxAge: null })
genid: 产生一个新的 session_id 时,所使用的函数, 默认使用 uid2 这个 npm 包。
rolling: 每个请求都重新设置一个 cookie,默认为 false。
resave: 即使 session 没有被修改,也保存 session 值,默认为 true
2.2 在内存中存储session
如下代码:
const express = require('express');
const session = require('express-session');
const app = express();
app.listen(3002, () => {
console.log('port listen 3002');
});
app.use(session({
secret: 'somesecrettoken',
cookie: { maxAge: 1*60*1000 } // 1分钟
}));
app.get('/', (req, res) => {
/*
检查session中的isVisit字段
*/
if (req.session.isVisit) {
res.send('再次欢迎你');
} else {
req.session.isVisit = true;
res.send('欢迎你第一次来~');
}
});
nodeJS之Cookie和Session(一)的更多相关文章
- nodejs中cookie、session的使用
因为http会话的无状态性,为了标记用户的登录状态,便出现了cookie.cookie分为很多种,有普通cookie.签名cookie.json cookie等,这里主要记录下在express应用中如 ...
- nodejs cookie与session
cookie.session cookie:在浏览器保存一些数据,每次请求都会带过来 *不安全.有限(4K) session:保存数据,保存在服务端 *安全.无限 ------------------ ...
- nodeJs学习-08 cookie、session
http-无状态的:两次访问之间,无区别,cookie可解决 cookie:在浏览器保存一些数据,每次请求都会带过来: 弊端:可以查看修改,并不安全.大小有限(4K) 读取--cookie-parse ...
- HTML5学习笔记(二十九):Cookie和Session
HTTP协议本身是无状态的,这和HTTP最初的设计是相符的,每次请求都是创建一个短连接,发送请求,得到数据后就关闭连接.即每次连接都是独立的一次连接. 这样的话,导致的问题就是当我在一个页面登陆了账号 ...
- Cookie , Session ,Session 劫持简单总结
cookie 机制: Cookies 是 服务器 在 本地机器 上存储的 小段文本,并伴随着 每一个请求,发送到 同一台 服务器. 网络服务器 用 HTTP头 向客户端发送 Cookies.在客户端, ...
- IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token
本文引用了简书作者“骑小猪看流星”技术文章“Cookie.Session.Token那点事儿”的部分内容,感谢原作者. 1.前言 众所周之,IM是个典型的快速数据流交换系统,当今主流IM系统(尤其移动 ...
- Cookie和Session在Node.JS中的实践(三)
Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...
- Cookie和Session的总结
1.开篇 在之前学习这一段的时候我一直有点没弄清楚,其实对Session这块的理解还可以,但是Cookie感觉始终还是欠缺点火候.之后的很长一段时间都基本上很少用Cookie了,渐渐的也淡忘了这一块的 ...
- java的会话管理:Cookie和Session
java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...
随机推荐
- linux下使用gcc编译运行C/C++程序
编译C 首先,程序编译过程有: 1.预处理(展开宏,头文件,检查代码是否有误) 2.编译(将.c转为汇编代码.s) 3.汇编(将汇编代码.s转为机器代码.o) 4.链接(将所有机器代码.o和库文件链 ...
- fllume 入门
flume flume 简介及核心概念 什么是flume Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,目前是Apache的顶级项目.Flume支持 ...
- Java学习笔记之——类与对象
1.参数的传递方式 1)值传递 2)引用传递 2.类和对象: (1)类的定义: public class 类名{ 类型 属性1: 类型 属性2: ……… public 返回值类型 方法名1(形参){ ...
- 【开发工具之eclipse】7、eclipse代码自动提示,eclipse设置代码自动提示
首先打开Eclipse开发软件,然后在工具栏的[Window],点击后找到弹出列表中的[Preferences]选项,然后点击这个选项 现在弹出的窗口就是JAVA开发人员常见的设置窗口了,我们依次 ...
- What is The Rule of Three?
Question: What does copying an object mean? What are the copy constructor and the copy assignment op ...
- Git实战手册(二): 标签应用和版本管理
教程所示图片使用的是 github 仓库图片,墙内朋友请移步原文地址 有空就来看看个人技术小站, 我一直都在 0. 背景介绍 当一个代码仓库进过长时间的迭代,针对不同的时期和需求,必定会有不同的版本. ...
- cache 访问频率的思考
互联网的项目用户基数很大,有时候瞬间并发量非常大,这个时候对于数据访问来说是个灾难.为了应对这种场景,一般都会大量采用web服务器集群,缓存集群.采用集群后基本上就能解决大量并发的数据访问.当然这个时 ...
- iOS开发-本地存储(偏好设置,Plist,归档)
1. NSUserDefaults //TODO: 1.NSUserDefaults NSUserDefaults类除了可以存储数组.字典.NSdata外,还可以直接存储OC基本类型属性.但是不能 ...
- 将你的 Virtual dom 渲染成 Canvas
项目概述 一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中.支持常规的滚动操作和一些基础的元素事件绑定. githu ...
- Appium初识
一. Appium工作原理 基本工作流程如下: Appium提供了一套web服务,Appium起一个Server(4723端口),用于与脚本client通信. server接收web driver(即 ...