全面了解cookie和session
- http协议:
http即超文本传输协议(万维网定义的),一种基于浏览器请求与服务器响应的链接,它是一个很纯粹的传输协议。http协议主要的特征就是它是一种无状态的协议(只针对cookie与session问题),在客户端连续向服务器发送请求的时候,每次请求的过程中只要数据交换完毕,服务器与客户端就会断开连接,再次请求的时候会重新连接客户端与服务器,这样服务器记录上次的对话,那么问题来了,如何让服务器知道是哪个客户端向自己发出的请求呢,这个时候cookie就诞生了~
- 什么是cookie
cookie是一小段文本信息,这段小文本信息由服务器首次响应客户端时发送的,在客户端向服务器首次发送请求的时候,服务器会判断是否要记录客户端的身份,如果需要,此时就会在响应中(response)给客户端发送一个cookie,该cookie文本信息保存在http的报头里,当浏览器会将cookie保存起来,当该浏览器再次发送请求时会携带cookie,服务器检查cookie来识别浏览器请求,这里cookie的特征就不在说明了。下面我们上代码!
页面代码:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
<script type="text/javascript" src='test.js'></script>
</head>
<body>
<section>
<h3>Register</h3>
<div>
<label style="display:inline-block; width: 100px;" id="register-user-name-label" htmlfor="register-user-name-input">register:</label>
<input style="display:inline-block; width: 200px;" id="register-user-name-input" type="text" />
</div>
<div>
<label style="display:inline-block; width: 100px;" id="register-password-label" htmlfor="register-password-input">pasword:</label>
<input style="display:inline-block; width: 200px;" id="register-password-input" type="text" />
</div>
<button id="register" type="button">Register</button>
</section>
<section>
<h3>Login</h3>
<div>
<label style="display:inline-block; width: 100px;" id="user-name-label" htmlfor="user-name-input">login name:</label>
<input style="display:inline-block; width: 200px;" id="user-name-input" type="text" />
</div>
<div>
<label style="display:inline-block; width: 100px;" id="password-label" htmlfor="password-input">pasword:</label>
<input style="display:inline-block; width: 200px;" id="password-input" type="text" />
</div>
<button id="login" type="button">Login</button>
</section>
<script type="text/javascript" src='test.js'></script>
</body>
</html>

很简单,一个注册按钮一个登陆按钮(ps:代码冗余请忽视,就是为了做个demo用)。
首先注册一个user:
注册user之后我们查看db

然后我们用这个user进行登陆操作,重点来啦~
首先刷新下页面,调用获取user方法,看下效果
代码如下:

app.get('/userInfo', function (req, res) {
//cookie
if (req.cookies.userInfo) {
console.log('login successfully')
}
else {
console.log('session timeout.');
}
res.status(200).json(req.cookies.userInfo);
//session
// if (req.session.userInfo) console.log('login successfully');
// else console.log('session timeout.');
})


好了先mark下,回头再来做对比,下面执行login操作,这里要上代码了。
首先引入一个中间件:
var cookie = require('cookie-parser');
使用它:

app.use(cookie('express_cookie'));
//cookie
app.post('/login', function (req, res) {
User.findOne({
username: req.body.username
}).then(function (userInfo) {
if (!userInfo) {
console.log('user is not exist.');
return;
}
var data = {};
data['username'] = userInfo.username;
data['password'] = userInfo.password;
res.cookie('username', JSON.stringify(data), { maxAge: 900000, httpOnly: true });
res.status(200).json(data);
})
.catch(function (e) {
console.log(e);
})
})

这里我们可以设置cookie的httpOnly属性,最大生命周期,等等,然后我们先在db内查询当前登录user,如果已经注册过,我们获取user信息并存入cookie中。这时候看下前端的响应有什么不同。

可以看见,服务器颁发的cookie在响应的header中的Set-Cookie中。似不似发现不同了。这时候我们在刷新下页面调用userInfo方法看下效果。

咦,我们发现这次的请求里面居然有cookie了,就这么神奇(Ps:我们要相信科学!)。
debug下看看

服务器端有我们想要的cookie信息了。这样服务器就可以根据cookie知道了我们每一次的请求是不是同一个人了。
总结:首先cookie是服务器颁发的,然后随着响应返回给客户端也就是我们的浏览器,浏览器保存cookie,每一次发送请求都会带着这个cookie来让服务器知道,嗯我就是上次的那个人,到这里对cookie是不是多少了解了一些呢~
好了,那么现在很多浏览器都是禁用cookie的,原因是啥呢~,由于cookie是可以被获取的以及cookie是可以修改的,这时候引出了web安全方面的姿势,跨站脚本攻击以及跨站协议伪造,可以参考我之前写的关于XSS攻击(戳我:什么是XSS以及CFRS),那么如果cookie禁用了我们该怎么办呢?这时候session就诞生了。
- 何为session:
session本省并不存在,只是一个概念,session是服务器用来记录客户端状态的机制,不同于cookie保存在浏览器中,session是保存在服务器上的,服务器会根据cookie生成一个session id存在服务器上,当请求再次抵达服务器时,服务器发出响应时会将session id 存在cookie内一同反回给浏览器,这就是session。session具体哪些特点这里就不写啦,话不多说,上代码。
首先引入一个中间件:
var session = require('express-session');
使用它

app.use(cookie('express_cookie'));
app.use(session({
secret: 'express_cookie',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 1000 * 30 },
rolling: true,
}));
app.post('/login', function (req, res) {
User.findOne({
username: req.body.username
}).then(function (userInfo) {
if (!userInfo) {
console.log('user is not exist.');
return;
}
var data = {};
data['username'] = userInfo.username;
data['password'] = userInfo.password;
req.session.userInfo = data;
res.status(200).json(data);
})
.catch(function (e) {
console.log(e);
})
})

现在我们登录一下看下效果:

会发现,多了一个Cookie,而且Cookie里面多了一个sid,不用联想了,这就是sessionId,这时候我们在刷新一下页面看下userInfo变成啥样了呢?

可以清晰的看到再次请求的时候,sessionId会装在Cookie中,然后发送给服务器,这时候服务器就知道了,咦,原来是上个人。这就是session。
由于现在服务器session存入的方式我们采用了服务器自带的内存,也叫session memory。如果server挂了怎么办呢,挂掉了内存就释放了啊,session就没了啊。这个时候就引出了另外一个问题,session的可持续化。
- session的可持续化
session的可持续化方式简单的理解就是让session可以在生命周期内一直存在,可以把session存入db中,可以是MongoDB,可以是redis,上代码,我们这里用MongoDB吧,个人比较喜爱。
引入中间件:
var MongoStore = require('connect-mongo')(session);

app.use(cookie('express_cookie'));
app.use(session({
secret: 'express_cookie',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 1000 * 30 },
rolling: true,
store: new MongoStore({
url: 'mongodb://127.0.0.1:27017/demo',
collection: 'sessions'
})
}));
app.post('/login', function (req, res) {
User.findOne({
username: req.body.username
}).then(function (userInfo) {
if (!userInfo) {
console.log('user is not exist.');
return;
}
var data = {};
data['username'] = userInfo.username;
data['password'] = userInfo.password;
req.session.userInfo = data;
res.status(200).json(data);
})
.catch(function (e) {
console.log(e);
})
})

http请求与响应部分我们就不看了,直接看server跟DB。
server中我们将userInfo放入session中
var data = {};
data['username'] = userInfo.username;
data['password'] = userInfo.password;
req.session.userInfo = data;
查看DB

咦,一条session就在DB中诞生了,这里要注意的是,session不是设置的时候就会存入DB中的,包括内存等等,而且响应成功的时候才会存入,一定要注意,不然坑的就是你。
然后刷新页面看下效果。

似不似,session中就有了user信息。好了到这里关于session持久化的问题也解决了。
登出功能就很简单了,销毁session就ok了,代码如下:
app.get("/loginOut",function(req,res){
req.session.destroy(function(err){
console.log(err);
})
res.send('退出登录成功');
});
Redis方式:
中间件以及使用:

var RedisStrore = require('connect-redis')(session);
app.use(session({
secret: 'express_cookie',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 1000 * 30 },
rolling: true,
store: new RedisStrore({})
}));

总结:第一次登陆请求的时候,服务器会颁发一个sessionId,响应的时候将sessionId放入cookie中返回给浏览器,此时session已存入DB中,当再次请求的时候携带着sessionId进入服务器中,获取session信息,服务器还是会记得我
全面了解cookie和session的更多相关文章
- Cookie和Session的总结
1.开篇 在之前学习这一段的时候我一直有点没弄清楚,其实对Session这块的理解还可以,但是Cookie感觉始终还是欠缺点火候.之后的很长一段时间都基本上很少用Cookie了,渐渐的也淡忘了这一块的 ...
- java的会话管理:Cookie和Session
java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...
- Cookie和Session的那些事儿
Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每 ...
- django的cookie和session以及内置信号、缓存
cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...
- Cookie和Session的区别
前言 HTTP是一种无状态的协议,为了分辨链接是谁发起的,就需要我们自己去解决这个问题.不然有些情况下即使是同一个网站我们每打开一个页面也都要登录一下.而Session和Cookie就是为解决这个问题 ...
- 本地数据Store。Cookie,Session,Cache的理解。Timer类主要用于定时性、周期性任务 的触发。刷新Store,Panel
本地数据Store var monthStore = Ext.create('Ext.data.Store', { storeId : 'monthStore', autoLoad : false, ...
- Cookie与Session
再说Cookie与Session之前,先要了解一下http协议. 何为http协议: http协议即超文本传输协议,一种基于浏览器请求与服务器响应的协议,该协议主要的特点就是它是一种无状态的协议(只针 ...
- 【转】Cookie和Session区别和联系详解
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...
- 理解Cookie和Session机制(转)
目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...
- cookie 和session 的区别详解
这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...
随机推荐
- luogu 3951 小凯的疑惑
noip2017 D1T1 小凯的疑惑 某zz选手没有看出这道结论题,同时写出了exgcd却不会用,只能打一个哈希表骗了30分 题目大意: 两个互质的正整数a和b,求一个最小的正整数使这个数无法表示为 ...
- 【BZOJ 3732】 Network
[题目链接] 点击打开链接 [算法] 求出这个图的最小生成树,对于每次询问,用倍增法求出最近公共祖先,查询最小生成树上两点路径上的最大值 算法的正确性? 假设x和y在最小生成树中 ...
- ZOJ2107 Quoit Design 最近点对
ZOJ2107 给定10^5个点,求距离最近的点对的距离. O(n^2)的算法是显而易见的. 可以通过分治优化到O(nlogn) 代码很简单 #include<iostream> #inc ...
- POJ3709 K-Anonymous Sequence 斜率优化DP
POJ3709 题意很简单 给n个递增整数(n<=500000)和一种操作(选择任意个数 使他们减少整数值) 使得对于所有的整数 在数列中 有k个相等的数 O(n^2)的DP方程很容易得出 如下 ...
- 短链接及关键字过滤ac自动机设计思路
=============:短链接设计思路:核心:将长字符转为短字符串并建立映射关系,存储redis中.1.使用crc32转换为Long 2.hashids将long encode为最短字符串.作为短 ...
- 在visual studio code和visual studio中编写TypeScript文件自动生成JavaScript文件
注:此处的自动生成都为保存ts文件时自动生成js文件 VS CODE 只需要在TypeScript的终端控制台中输入如下命令即可,并注意需要将其中的*换成对应的文件名,此处的*似乎不能作为通用匹配. ...
- Akka源码分析-Akka-Streams-概念入门
今天我们来讲解akka-streams,这应该算akka框架下实现的一个很高级的工具.之前在学习akka streams的时候,我是觉得云里雾里的,感觉非常复杂,而且又难学,不过随着对akka源码的深 ...
- spring的annotation
spring容器创建bean对象的方式: 1,使用反射调用无参构造器来创建实例(前提是这个类有无参构造器)(常规方式) 2,通过工厂类获得实例(工厂类实现了接口FactoryBean<?> ...
- php 文件上传限制修改
修改PHP上传文件大小限制的方法 1. 一般的文件上传,除非文件很小.就像一个5M的文件,很可能要超过一分钟才能上传完.但在php中,默认的该页最久执行时间为 30 秒.就是说超过30秒,该脚本就停止 ...
- Linux文件详解
一.Linux文件类型分:普通文件.目录文件.链接文件.设备文件.管道文件. 1.普通文件:由ls -al显示属性时,第一个属性为 [-],例如 [-rwxrwxrwx].包括: 纯文本文件(ASCI ...