在web开发中,总是有看到cookie还有session这两个东西,那么它们到底有什么用?本人将在这篇文章为你们介绍一下个人对cookie和session的理解。
因为http协议是无状态的,每次的请求访问都是独立的,没办法追踪到上一次访问的状态,后端就无法知道这次的访问是哪位,所以就要一些技术来帮助后台辨别这次的请求是谁。而这两者Cookie与Session都是Web程序中常用的技术,用来跟踪用户的整个会话。
- Cookie通过在客户端记录信息确定用户身份,(相当于你有一张身份证,跟后端交流前要拿出身份证给后端看一看,然后后端根据你的身份证才能确认你的身份。)
- Session通过在服务器端记录信息确定用户身份。(你不用身份证,你只要说出自己的名字,然后后端在它们用户簿上找一找有没有你的名字,最终确认你的身份。)
了解了它们的大概后,我们现在深入了解它们吧。以及了解什么情况使用session或者cookie。
一,session
1,session简介
Session是服务器端使用的一种记录客户端状态的方法,虽然简单而且安全一些,但是会把用户信息存放在后端的内存中,导致内存变大,可能会导致溢出(后文会讲到解决方法)。
2,session是怎么运行的
当你开始跟后端联系的时候,后端就会根据你的情况给你分配一个sessionid(唯一),这个sessionid就会存放在cookie中,而且cookie中只需要存放这个信息就行了,后端设置这个sessionid存在的最长时间,时间到了自然这个sessionid就消失了,同时后端中的相应内存也会释放。
有了这个sessionid后,每次跟后端交流,都会拿着这个id去校验一下,确保后端明白你的身份,身份确认后,就可以开始交流了。
3,session实现登陆
const session = require('koa-generic-session')
app.keys = ['xiamo']
app.use(session({
//配置cookie
cookie: {
path: '/',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000 //存在的最长时间
},
//配置redis
store: redisStore({
all: '192.168.43.245' //写死本地redis
})
}))
//登陆后session中就会有你的信息,每次跟后端的交流前都要验证你的身份,并且更新最后交流时间,只有当session过期了,你跟后端的会话才要重新登陆。
4,Session的生命周期
Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。
5,Session常用方法
- secret:一个String类型的字符串,作为服务器端生成session的签名。
- name:返回客户端的key的名称,默认为connect.sid,也可以自己设置。
- resave:(是否允许)当客户端并行发送多个请求时,其中一个请求在另一个请求结束时对session进行修改覆盖并保存。
默认为true。但是(后续版本)有可能默认失效,所以最好手动添加。 - saveUninitialized:初始化session时是否保存到存储。默认为true,但是(后续版本)有可能默认失效,所以最好手动添加。
- cookie:设置返回到前端key的属性,默认值为
{ path: '/', httpOnly: true, secure: false,maxAge: null }。
- Session.destroy():删除session,当检测到客户端关闭时调用。
- Session.reload():当session有修改时,刷新session。
- Session.regenerate():将已有session初始化。
- Session.save():保存session。
6,如何解决session存放在后端,内存溢出,或者后台多进程间内存不共享问题。
可以使用redis,重新开一个进程,将服务器上的几个后台进程的session信息存放在redis中,既可以解决内存溢出的问题,又可以解决进场间通讯的问题,但是有可能会引发redis的其他问题,这又是另外的一个知识点了,不在本文的讨论范围。但是合理的后台编写,是可以解决这个问题的。
二,cookie
1,Cookie简介
客户端请求服务器,如果服务器需要记录该用户状态,就向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。(也就是给你一个身份证,上面记录了你的信息,每次跟后台的交流前,后台都要看看你的身份证过期了没,然后才跟你通话。)
2,Cookie的不可跨域名性
既然这些信息都是存放在我们的客户端(浏览器)上,那么浏览器上面存放了这么多的cookie,就不会混乱吗,比如我访问qq的网址,拿了阿里的cookie(身份证),就过去了?
答案是不会的,浏览器的合格与否,就是要看看它的cookie是否会存放和使用好。跨域的cookie是不能够共享的。
3,cookie安全性
既然是存放在客户端上,那么就会存在被修改的危险,如果这个cookie是明文存放的,那么我相信小白也能够随意更改信息(相当于你把你的身份证改成了别人的名字,然后就冒充那个人去跟后台交流)。
早期的cookie确实存在这样的问题,但是肯定要进步,就给加密起来了,现在你的cookie上面都是乱码,只有后台程序才知道这个乱码要怎么解密,变成你的身份,我们乱修改就会导致你的身份证失效。
4,cookie的效率
由于每次跟后台访问的时候,都要携带上这个cookie,我们坐一个假设,如果我们的cookie是5kb,然后我打开csdn的首页,它上面是首页要请求的次数是200多次,那么在打开首页的过程中,就要消耗5kb×200多=1mb多的流量。
我们才只是打开一个页面而已,光是身份证验证就已经消耗了1MB的流量了,而且还没算上200多次请求返回来的数据流量,算上图片,文字啥的,你打开一次首页就要消耗几MB。
所以我们要将cookie的大小压缩一下,不必要的就不放进去了,太浪费流量和效率了。