cookie、session、token
cookie
cookie存储在客户端,是客户端专门存东西的一个标识。
特点:
- ①能存储的东西很少,基本上只能存储4K左右的东西;
- ②存储在浏览器,能被手动清除,有效期不高,可以自行设置,一般正常没有操作后20分钟就被清除,如果没设置,默认浏览器关闭后失效;
- ③cookie安全问题,别人能从本地cookie中获取信息;
- ④cookie不能直接存储中文,如果需要,则需要进行url转码(URLEncode.encode(value, utf-8), URLEncode.decode(value, utf-8);
- ⑤cookie的存储格式是key-value;
- ⑥cookie的有效范围:当前域名范围下有效(当前后端项目协议一致,域名、端口号都一致,即在同一个项目下)
作用流程:客户端A访问服务器,服务器返回cookie给客户端A,客户端A存储 cookie,下次需要带着cookie访问服务器,服务器返回相应的数据。
session
session存储在服务器端,是服务器专门存东西的一个标识
特点:
- ①安全性:session的安全性比cookie的安全性要高;
- ②性能:当服务器访问较多,比较占用性能;
- ③生命周期:异常关机会造成session的销毁,默认存储30分钟;
- ④session的钝化以及活化:钝化即服务器正常关闭后,tomcat会自动将session数据写入硬盘的文件中,活化即服务器再次启动后,从文件中加载数据到session中;
- ⑤浏览器关闭后再次重启sessionId的地址值不为同一个;
- ⑥访问范围:session为一个浏览器共享,cookie为多个浏览器共享
作用流程:客户端A访问服务器,服务器存储A的数据value,把key返回给客户端A,客户端A下次带着key(session ID)来访问服务器,服务器就能给出客户端A的数据。如果负载均衡,客户端A访问了另一个服务器,那个服务器没有客户端A的数据。
基于session认证访问
作用流程:用户登录后服务器会为登录用户创建一个session,cookie的验证是有状态的,sessionId会保存在用户浏览器的cookie中。当用户登录成功后,cookie会随着后面的每一个请求一起发送。这样,服务器通过cookie的sessionId找到内存中的session数据来验证用户身份呢,从而在响应中返回相应的状态。
特点:
- ①session是服务端存储的一个对象,主要用来存储所有访问过改服务端的客户端的用户信息(也可以存储其他信息),从而保持用户会话状态。但是当服务器重启后,内存会被销毁,存储的用户信息也就消失了。
- ②不同的用户访问服务端的时候会在session中存储键值对,键用来开启用户登录的钥匙,登录成功后,钥匙通过cookie返回给客户端,客户端存储sessionId在cookie中,客户端再次访问时会携带cookie中的sessionId进行访问。
- ③session是基于cookie的。
- ④当客户端存储的cookie失效后,服务端的session不会立即销毁,会有一个延时,服务端会定期清理无效session,不会造成无效数据占用存储空间的问题。
- ⑤session持久化,用于解决重启服务器后session就消失的问题,在数据库中存储session,而不是存储在内存中。可通过包:express-mysql-session实现。
token
token是开发定义的,和session有些类似。
特点:
- ①token是开发定义的,session是http协议规定的;
- ②token不一定存储,session存储于服务器;
- ③token可以跨域,session不一定能跨域,会与域名绑定
作用流程:客户端A访问服务器,服务器给了客户端token,客户端A拿着token访问服务器,服务器验证token,返回数据。
基于token认证访问
作用流程:很多网络应用使用json web token也即JWT来代替session来实现身份认证。在这种基于token的应用中,服务器使用一个密钥来创建jwt并发送给客户端。客户端会保存此jwt(通常保存在本地存储local storage中,也可以在cookie、sessionStorage中)并在每个请求的header中包含此jwt,再次请求时不会默认携带,需要在请求拦截器位置给请求头中添加认证字段Authorization携带token信息。服务器验证客户端发来的每个请求中的jwt做出响应。token的验证是无状态的,存储在Authorization Header中进行验证,形式是Bear{JWT}.
特点:
- ①它与session方式最大的不同是用户状态不存储在服务器端,而是存储在token中并保存在客户端。为了扩展性,大部分现代网络应用都是应用jwt来进行用户认证。
- ②token的组成一般是uid(用户唯一身份标识)+time(时间戳)+sign(签名使用hash压缩成固长的十六进制字符串 防止第三方恶意拼接)+固定参数可选。
- ③适用于项目级的前后端分离(前后端代码运行在不同的服务器下)
对比基于session的访问认证:
- ①基于session的访问认证,由于session存储于服务器端(一般是内存型数据库,如redis),当用户量很大时会有一定的扩展性问题;基于token的访问认证,存储在客户端,不存在上边这个问题。
- ②token可以抵抗csrf(跨域请求伪造),更安全,使用cookie在post请求的同时会自动添加到请求头上,token则不会自动添加在请求头上去。攻击者也无法访问用户的token,无法形成攻击。
- ③基于session的访问认证,cookie通常工作在单个域名或其子域名下,而且跨域名时通常会被浏览器关闭。当API要服务于不同域名的移动和网络设备时,容易出现问题;基于token的访问认证,由于jwt包含于请求头中,不存在cookie引发的相关问题。