美丽定制 网站模板,辽宁做网站,建设银行纪检监察网站,说一说网站建设的含义一.技术选型
1.为什么不用SessionCookie#xff0c;而要用Token?
【1】无状态
什么是无状态服务
无状态服务是指在处理请求时不存储任何会话信息或状态信息的服务。这意味着每个请求都是独立且相互独立的#xff0c;服务不会在请求之间保留任何状态。
Session-Cookie方…一.技术选型
1.为什么不用SessionCookie而要用Token?
【1】无状态
什么是无状态服务
无状态服务是指在处理请求时不存储任何会话信息或状态信息的服务。这意味着每个请求都是独立且相互独立的服务不会在请求之间保留任何状态。
Session-Cookie方案的缺陷 先回顾一下使用Session-Cookie方案 1.用户成功登陆系统会创建一个会话对象Session然后返回给客户端器对应的SessionID的Cookie 。 2.当用户向后端发起请求的时候会把 SessionID 带上。拿到这个SessionID后后端就可以找到对应的Session从而获取你的身份状态。 单体项目用Session-Cookie方案是不错的但是对于微服务项目Session-Cookie方案就面临挑战。
举个例子用户在A服务器进行了登录此时用户的 Session 信息保存在 A 服务器。但是用户下次请求B服务器需要用到该Session信息此时由于 B 服务器没有保存 用户的 Session 信息导致用户需要重新进行登陆。 存在一些解决方案。例如有几个方案可供大家参考 1.某个用户的所有请求都通过特性的哈希策略分配给同一个服务器处理。这样的话每个服务器都保存了一部分用户的 Session 信息。服务器宕机其保存的所有 Session 信息就完全丢失了。 2.每一个服务器保存的 Session 信息都是互相同步的也就是说每一个服务器都保存了全量的 Session 信息。当节点多的时候同步成本高并且系统的一致性和可靠性也会收到影响。 3.单独使用一个所有服务器都能访问到的数据节点比如缓存来存放 Session 信息。为了保证高可用数据节点尽量要避免是单点。 4.Spring Session 是一个用于在多个服务器之间管理会话的项目。它可以与多种后端存储如 Redis、MongoDB 等集成从而实现分布式会话管理。通过 Spring Session可以将会话数据存储在共享的外部存储中以实现跨服务器的会话同步和共享。 使用Token代替会话技术实现无状态认证
在JWT的中自包含了身份验证所需要的信息因此我们的服务器不需要存储 Session 信息。只需要在登录的时候返回给客户端一个Token密钥然后每次请求各个微服务都携带这个Token解析获得用户信息即可。这种方案解决了原来Session-Cookie方案的问题并减轻了服务端的存储压力从而实现无状态服务。
【2】防止CSRF
CSRF(Cross Site Request Forgery) 一般被翻译为 跨站请求伪造 。
那么什么是跨站请求伪造呢说简单点就是用你的身份去发送一些对你不友好的请求完成需要你权限的操作。
举个例子比如银行转账的链接如果如下
http://www.mybank.com/Transfer?bankId11money10000
这个转账肯定需要你的权限如果用Cookie因为Cookie是无感知的发送你点击链接的同时自动携带了带有sessionId的Cookie那这个操作无意间完成了然后你钱就没了。
而JWT一般会存放在localStorage 中。与Cookie不同的是它不是点击链接就自动发送的前端的每一个请求后续都需要通过JS代码附带上这个 JWT。所以即使你点击了链接这个请求也不会完成因为没有权限。
总结来说Cookie无感知发送需要你的权限的相关操作点击个链接就可能被完成。而JWT需要通过代码单凭一个链接无法实现CSRF。
【3】适合移动端
移动端不能用想网页端一样的Cookie。然后如果硬要用session的话可能不同平台有不同的传递sessionId的方式。
而JWT是通用的。
【4】适合单点登录
首先服务端不同设备之间的session无法互通。 其次cookie不能跨域比如sso.example.com接收的cookie只能在本域名下发送如果用户尝试在另一个域名如app.example.com下发送请求浏览器会根据同源策略阻止该 Cookie 被发送到另一个域名。除非在服务端允许跨域。
2.为什么不直接用账号和密码加密传回而是用Token
【1】防止密码盗窃
因为如果用密码和账号加密传回的话如果被窃取用来伪造请求这时候我们就必须让密码失效。而如果是Token我们只需要在缓存中将token失效即可。一般有缓存来控制token状态
【2】无状态
在JWT的中自包含了身份验证所需要的信息因此我们不用再去数据库中查。
二.相关功能实现
我们一般会用Redis维护Token一般采用黑名单和白名单。
黑名单的话是指维护登出注销但未过期的Token白名单是维护有效的Token。
1.登出功能的实现
【1】黑名单
登出的时候将过期的Token存入黑名单。每次请求判断是否在黑名单中。
【2】白名单
创建Token存入白名单中注销的时候把Token删除。每次请求判断是否在白名单中。
2.实现单账号登录顶号和控制多账号登录
需要使用白名单。
单账号登录键为userId,值只能一个。这样在另一个设备重新登录则原先Token就被代替实现顶号。
多账号登录键为user值可以list。可以控制列表的长度控制登录设备的多少。
3.续签无感知登录--双Token
第一个是 accessJWT 它的过期时间 JWT 本身的过期时间比如半个小时另外一个是 refreshJWT 它的过期时间更长一点比如为 1 天。refreshJWT 只用来获取 accessJWT不容易被泄露。
客户端登录后将 accessJWT 和 refreshJWT 保存在本地每次访问将 accessJWT 传给服务端。服务端校验 accessJWT 的有效性如果过期的话就将 refreshJWT 传给服务端。如果有效服务端就生成新的 accessJWT 给客户端。否则客户端就重新登录即可。
这种方案的不足是
需要客户端来配合用户注销的时候需要同时保证两个 JWT 都无效重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况可以通过在客户端设置定时器当 accessJWT 快过期的时候提前去通过 refreshJWT 获取新的 accessJWT;存在安全问题只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。不过由于 refreshJWT 只用来获取 accessJWT不容易被泄露。