Http是无状态的请求-应答协议。HTTP在1.0版本引入了重要设计在报文中增加了Header属性列表,每个Header都是一个Key/Value键值对,整个Header列表可以被视为一个Map数据结构,Header与请求或响应的正文是互相独立的,并且用户可以灵活扩展。采用了HTTP作为通信协议的分布式系统天然具备了无侵入性的基础设施能力全面改进的优势。
想要让HTTP请求有状态,可以通过header上的cookie。
Cookie
HTTP Cookie新增的两个扩展性的HTTP Header,其中一个是Set-Cookie。Set-Cookie是服务段专用的Header,可以在浏览器的Response Header中看到。告知浏览器,刚刚调用这个接口的用户现在有状态。当set 了cookie之后,每次该浏览器,同域的HTTP请求都会带有该Cookie信息。
Cookie属性:
Cookie 最重要的是name value 键值对。
- expires: cookie的过期时间
- path: cookie的路径,一般为了都能读到,设置根路径 /
- domain: 域,可访问该Cookie的域名,如:
.baidu.com
- secure: true or false。
- SameSite 限制第三方 Cookie,从而减少安全风险。Chrome浏览器升级后对这个属性做了判断。默认SameSite的值为Lax
- None 网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送)
Set-Cookie: widget_session=abc123; SameSite=None; Secure
- Strict 最严格状态,不允许第三方站点设置Cookie
- Lax 只支持get请求的cookie传递
- None 网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送)
- HttpOnly 设置后js脚本读取不到cookie
Set-Cookie
服务器在response Header中携带Set-Cookies时,一般会有jessionid(Tomcat标识用户)。而PHP中通常使用phpsessionid。
Session
Session是由服务器来维护的,服务器在收到上述请求(比如jsessionid)后,就会检查Cookie里的数据,抽取用户ID并对应到服务器端的用户会话(Session)对象。通常在Session(HttpServletRequest 中可以获取cookie对应的session信息)中会保存更多的用户数据,比如用户的昵称、角色、权限及更多的特定数据。与在Cookie中保存的数据相比,在Session中保存的内容通常是一些复杂的对象和结构体。
在分布式的情况下,云服务状态,应用都是多实例的,也就是说多次访问的接口可能是由不同的服务器接受的。就有可能存在 用户信息在A服务器能查到,到了B服务器就丢失了。
Token
Token本质上是Session的改进版本,与Session将用户状态保存在服务器端的常规做法不同,Tokne机制则把用户状态信息保存在Token字符串里。服务器端就可以做到无状态。
标准做法
将Token放到HTTP Header “X-Auth-Token”中保存并传输,但客户端拿到Token以后可以将器保存在本地。
JWT
JSON Web Token,每个JWT对象都是一个字符串
JWT组成
- 头部(Header):声明签名算法,对称加密算法(HMAC SHA256,简称HS256)和非对称加密算法(RSA)。
- 载荷(Payload):Map字典,有exp字段表明JWT的失效时间。
- 签名(Signature):将Header与Payload内容加在一起用Header声明的算法进行签名。
结合Spring使用JWT
使用处
1. filter
2. 拦截器
JWT续约
用户一直是在登录状态下进行操作的,但是JWT他有自己的过期时间,就有可能造成网页用到一半时因为JWT过期而弹出登录框。这样用户体验是非常不好的。
- redis再存一份两倍过期时间的数据,等jwt过期时,查询redis是否超过两倍时间,没超过两个时间都续约。若超过了就弹出登录。
- 还有就是快过期就给他续约,自己设置一个阈值比如
当前时间-过期时间<10min
。
结合redis
相关技术:OAuth2.0和OpenID相关技术。