文章目录
- 引言
- 正文
- Cookie——客户端存储和管理
- Session——服务端存储和管理
- Token
- 补充
- 签名和加密的区别
- 常见的加密算法和签名算法
- 面试题
- 1、HTTP用户后续的操作,服务端如何知道属于同一个用户?如果服务端是一个集群机器怎么办?
- 2、如果禁用了Cookie,怎么实现Session
- 3、Cookie、Session和Token有什么区别?
- 4、JWT原理和校验机制
- 5、JWT令牌为什么能够就解决集群部署问题
- 6、JWT的缺点
- 7、什么是跨域?什么情况下会发生跨域请求?
- 总结
引言
- 马上要面试了,总是觉得会被问到对应的cookie、session和token等解决HTTP无状态的一些协议,这里就整理一下。
- 除此之外,心里比较紧张,因为估计是最后一轮技术面,过了这个我秋招算是结束了一半了吧!
- 先别扯这些,继续看吧,不能浪费时间,面试完了,晚上好好整理一下,然后在刷两道题目。
- 参考信息
- 图解|cookie、session、token的那些事儿
- 19 让我知道你是谁:HTTP的Cookie机制
- 凤凰架构——凭证
正文
- HTTP本身是无状态,但是很多应用都是基于状态记录实现的,电子商城要记录用户购买商品数量、视频网站需要记录用户的登录状态和保存用户的浏览记录。
- 主要是通过cookie、session和token解决
Cookie——客户端存储和管理
1、基本介绍
- 提示作用的小纸条
- 是服务器发送到客户端浏览器,并保存在本地的一小块数据,会在浏览器下次向同一服务器再次发送请求时,被携带并发送到服务器上。
- 具体作用
- 身份识别,管理会话事物:告知服务端两个请求是否来自同一个浏览器
- 对网页的个性化设置:用户自定义设置、主题等
- 广告跟踪:第三方收集你访问目标网站的cookie,然后针对性的对你投放广告
2、Cookie的创建交互过程
- 服务端Set-Cookie标记
- 服务端受到客户端的HTTP请求后,在返回的响应中,会添加set-cookie字段
- 其中包含了创建的独特的身份标识数据“key=value”
- 服务端受到客户端的HTTP请求后,在返回的响应中,会添加set-cookie字段
- 客户端保存cookie
- 客户端收到请求之后,会保存下Cookie
- 后续每一次请求,都附加Cookie信息发送给服务器
- 如果更换了浏览器就没有办法再次成功创建链接
3、具体交互过程见下图
4、存在的问题
- 明文传输:
- 容易被劫持攻击
- 跨站伪造请求:利用你的cookie向银行发起转账请求
- 网络负载高
- 每次发送信息都会有额外的流量消耗
- 数量和容量限制
- cookie有容量和数量的限制,无法发送复杂消息
- 潜在的网络攻击
5、Cookie中包含的信息字段
- Expires
- 过期截至时间
- Max-Age
- 最大生存时间,接受时间+最大生存时间 就是过期时间
- 作用域
- Domain:当前cookie发送给特定的网站域名
- Path:访问路径
Session——服务端存储和管理
1、简介
- Session表示服务器和浏览器的一次会话过程
- 完全由服务端掌握
2、通信流程
-
1、保存通信信息并生成Session ID
- Session机制将用户的所有活动信息、上下文信息、登录信息等存储在服务端
- 根据会话信息生成一个唯一标识的ID发送给客户端
-
2、客户端保存SessionID标签并放置在请求头上
- 客户端保存,并在后续的通信中,将Session ID放在请求头
-
3、客户端验证SessionID读取通信细节
3、主要实现方式
-
Cookie
- 首选,默认开通并使用的方式
-
URL重写
- 将会话标识号以参数的形式附加在超链接的URL地址后面
4、存在问题
-
海量用户时,巨大的存储压力
- Session存储在服务端,用户量很大的场景,占用空间会很多
-
分布式系统中的信息共享问题
- 分布式系统中使用不同的机器存储Session,会有共享问题,无法保证访问的Session在当前机器中存在
- 信息复制和重建浪费资源
- 定制化哈希,将session映射到不同的机器上
- 使用session代理实现信息共享。
- 分布式系统中使用不同的机器存储Session,会有共享问题,无法保证访问的Session在当前机器中存在
Token
1、简介
- 服务端根据客户端发送过来的信息生成的令牌,发送给客户端
- 具有时效性的一种验证身份的手段
2、交互流程
- token生成过程
- 准备载荷PayLoad
- 以Json的格式保存用户非敏感信息,但是能够表示用户 状态的信息
- 编码载荷PayLoad
- 将json转成字符串 ,并使用Base64编码
- 准备头部header
- Token类型和哈希算法
- 组合头部和载荷
- 使用.连接起头部和载荷
- 生成签名
- 头部 + 载荷》特定哈希算法生成哈希值》私钥进行签名
- 将签名的结果进行Base64编码
- 组装和发送Token
- 头部(base64编码).载荷(base64编码).签名(base64编码) 进行连接,形成token串,然后进行发送。
- 准备载荷PayLoad
- token验证过程
- 提取Token
- 提取token中的header字段和PayLoad字段
- 生成临时signature
- 使用服务端保存的密钥,base64编码下的header和payload进行加密,生成临时签名
- 比较签名是否修改
- 比较临时signature和原来的signature是否相同的
- 相同,说明没有修改过,验证是否过期,没有过期就处理请求
- 不同,说明已经修改过了,不合法,返回失败信息401(未授权状态码)
- 比较临时signature和原来的signature是否相同的
- 提取Token
补充
签名和加密的区别
1、目的不同
- 加密:
- 保护数据的机密性,防止未经授权的人访问和读取数据
- 只有授权用户才能解密的格式
- 对于对称加密而言,就是同时持有密码的两方才能解密
- 对于非对称加密而言,就是公钥进行加密,然后私钥进行界面,持有私钥的才能获取信息
- 签名:
- 验证数据的完整性和来源的真实性——发送者有很多,只有持有私钥发送的才是合法的
- 签名
- 持有私钥方,对数据进行加密。(其他人持有公钥可以解密,但是没有私钥,没有办法加密,所以无法修改)
- 接收方使用发送方的公钥的来验证签名的有效性,确认数据在传输过程中是否被更改过。
2、使用方式不同
-
加密
- 非对称加密
- 公钥进行加密,私钥持有者进行解密,是单向发送的
- 对称加密
- 通信双方使用相同密钥,双向通信
- 非对称加密
-
签名
- 私钥
- 对数据进行签名,生成签名文件
- 签名者持有的,Token中就是的服务端就是签名持有者
- 公钥
- 对签名进行验证,对私钥进行解密,验证数据是否完整
- 公开给所有需要验证签名的人
- 私钥
常见的加密算法和签名算法
签名算法
- RSA
- DSA
- ECDSA
加密算法
- 对称加密算法
- AES、ADS、IDEA
- 非对称加密算法
- RSA、RCDHE
面试题
1、HTTP用户后续的操作,服务端如何知道属于同一个用户?如果服务端是一个集群机器怎么办?
Session Cookie机制
- 通过session cookie机制实现用户登录状态的管理
- 服务端验证客户端的用户信息后,通过验证会对当前的会话生成唯一的session id,分别保存在服务器端以及通过cookie 发送给客户端,并设定set-cookie字段
- 后续客户端在访问网站时,将带有session id的cookie发送给服务端,服务端通过匹配数据库来获取之前的用户信息,避免重复登陆
集群请求
- ** redis保存所有Session ID**
- 使用redis作为缓存保存所有的Session ID,然后由redis进行session id的检索和判定
- 单点故障,多机部署成本高
- 使用JWT
- JWT的状态信息是保存在客户端的,不过会附加上对应的signature,防止token被修改
2、如果禁用了Cookie,怎么实现Session
- 一般是通过cookie传输session id的
- 可以通过重写URL来实现,在URL中增加一个字段sessionid=
3、Cookie、Session和Token有什么区别?
存储位置
- Cookie是存储在客户端,通过HTTP头传递给服务器来通信
- Session是存储在服务端,服务器的内存或者数据库
- Token存储在客户端,但是以加密的方式存储在客户端LocalStorage和SessionStorage中
安全性
- cookie存储在客户端,存在窃取和篡改的风险
- Session存储在服务端,通过session-id在客户端和服务器之间进行关联,避免敏感数据直接暴漏
- Token加密算法生成,有效期短,并且单向不可逆
跨域支持不同
- Cookie不支持跨域传输,不同域名下cookie不能混用
- Session不支持跨域传输,Session一般是通过cookie来传输SessionID
- Token是保存在客户端的localStorage,并且作为请求头的一部分发送给服务器,不同域名的Token可以共享,只要的密钥共享就行了
状态管理不同
- cookie是应用程序通过在客户端临时存储数据,实现状态管理的一种机制
- session是服务器记录状态的方式,为每一个会话分配一个session ID,并将其和用户状态相关联
- token是用于认证和授权的机制,表示用户的身份信息和权限信息
4、JWT原理和校验机制
- 如下图
-
生成token
- 服务器校验用户的账号和密码,然后生成token,主要有三部分构成,分别是header和payload
- header指明了当前token的类型,默认一般是jwt,然后签名算法是加密这个token的常见的加密算法
- payload是负载,包含了用户的标识符,用户的权限信息,
- 然后对payload和header分别进行base64编码,并使用.链接
- 接着使用指定的签名算法,使用保存在服务端的私钥对前两者的链接进行加密,生成signature,然后再用base64编码
- 最后将上述三者使用.链接,然后在发送给客户端
-
校验token
- 获取token中的header和payload,然后使用保存的密钥对其进行加密,生成临时token
- 然后再和signature进行比较
-
5、JWT令牌为什么能够就解决集群部署问题
- JWT中包含了用户的身份、状态等信息,这些信息是保存在客户端的,然后服务端只需要保存的对应的私钥就行了!
6、JWT的缺点
1、难以主动失效
- 一旦签发,所有的逻辑都和服务器无关,除非另外自动到期失效。
- 黑名单:将需要额外判断失效的令牌存起来,如果在这里面就默认是无效的
2、防盗用
- 黑名单:将需要额外判断失效的令牌存起来,如果在这里面就默认是无效的
- 令牌里面含有用户的身份认证信息,一旦泄露很危险,所以一般设置的过期时间都比较短
7、什么是跨域?什么情况下会发生跨域请求?
同资源的定义
- 协议、端口、域名相同
- 限制一个网页中的脚本只能访问同源下的资源,不能访问其他域下的资源
跨域限制
- 跨域请求在浏览器上是不被允许的,只要在浏览器上发生了跨域请求,就会报错,No Access-Control-Allow-Origin
绕过跨域限制的方式
- 使用反向代理
- 通过Nginx等工具设置反向代理,将请求发送到目标服务器
- CORS跨域共享技术
总结
- 目前是将cookie、Session还有token都画图画了一遍,理解更加深刻了,基本上很多东西都是可以根据这个图片内容推导出来的!
- 加油!继续准备面试!