用户三种登录方案
用户三种登录方案
JaronToken 生成方式
Token 的生成方式通常有以下几种:
- 随机字符串:可以使用一些随机数生成算法,如 UUID、Snowflake 等来生成一个随机的字符串作为 Token。由于随机字符串本身就是随机分布的,因此具有很高的安全性。
- JWT(JSON Web Token):JWT 是一种基于 JSON 格式的开放标准(RFC 7519),用于在多方之间安全地传输信息。它将用户身份信息和权限等相关信息编码成一个 JSON 对象,并通过数字签名或者加密等方式进行验证和保护。JWT 除了可以用于 Token 登录外,还可以用于 API 认证、单点登录等场景。
- SessionID。
Cookie + Session 登录
HTTP 是一种无状态协议,这意味着服务器在处理每个请求时不会保留之前的请求信息,无法跟踪客户端的状态。每次客户端发起 HTTP 请求,服务器返回数据后并不会存储任何有关该请求的信息。
为了解决 HTTP 无状态的问题,引入了 Cookie 机制。Cookie 是服务器发送给客户端的一个特殊信息片段,以文本形式保存在客户端。当客户端再次请求时,会自动附带 Cookie,帮助服务器识别并“记住”客户端的状态。
用户在前端输入账号和密码,点击登录后将信息提交到服务器端。
服务器验证账号和密码无误后,生成一个新的 Session,用于在服务器端维护用户的会话状态,从而识别该用户的后续请求。
服务器将 Session ID(通常为一个唯一的随机字符串)通过 Cookie 返回给前端。浏览器会将这个 Cookie 保存下来,以便在后续请求中自动附带,确保用户状态的持续。
在后续的请求中,浏览器会自动携带保存的 Cookie 向服务器发送请求。服务器通过验证 Session ID 来确认用户身份。如果 Session ID 有效,服务器则返回相应的数据;若 Session ID 无效或已过期,则要求用户重新登录。
当用户选择退出登录时,服务器会清除对应的 Session 信息,使得该 Session ID 失效,确保用户的登录状态终止。
缺点
跨域访问受限:由于 Cookie 在同一域下共享,不同域之间无法直接访问 Cookie。在跨域请求时,可能会遇到访问受限的问题,此时可以考虑使用其他跨域技术,例如 JSONP、CORS 等来实现。
扩展性挑战:Session 数据保存在服务器端,随着系统扩展到多台服务器,Session 同步会成为问题。为防止 Session 数据不一致或丢失,通常需要集中式的 Session 存储方案。
兼容性问题:一些浏览器或移动设备可能禁用了 Cookie 和 Session 机制,这可能导致用户无法正常登录或保持会话。
总结
给服务器的
sessionID其实就相当于是一个token,只不过前端是无感知的设置进cookie的,这种方案 通常适用于后台。客户端主动存储的替代方案:为了避免 Cookie 的限制,可以考虑将 Token 存储在 localStorage 中,并在每次请求时由前端主动添加到请求头,以提高兼容性和灵活性。
集群环境下的集中管理:由于现代系统多采用集群部署,建议对 Token 进行集中管理,或选择无状态的 Token 方案,以便在多服务器环境中保持一致性和高可用性。
JWT实现Token
JWT(JSON Web Token)是一种用于在客户端和服务器之间传递认证信息的无状态令牌。它由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature),使用 Base64 编码后通过“.”连接成一个字符串。
JWT 的基本结构
Header(头部):包含令牌类型(通常是 “JWT”)和签名算法(如 HMAC SHA256)。
Payload(载荷):存放用户信息和其他声明(Claims),例如用户 ID、过期时间等。
Signature(签名):用来验证数据完整性,确保 Token 未被篡改。
工作流程
用户登录时,服务器生成 JWT,并将用户信息存入 JWT 的载荷中。
JWT 返回给客户端,客户端通常将其保存在 localStorage 或 sessionStorage 中。
每次请求时,客户端将 JWT 放入请求头,服务器根据签名验证 JWT 的有效性。
如果 JWT 有效,服务器允许访问,否则返回未授权的响应。
JWT 的优缺点
优点:
无状态:服务器无需存储用户会话信息,需要做任何查询操作,省掉了数据库/Redis的开销,减轻了服务器负担。
适合分布式系统:JWT 是自包含的,适合多服务器或微服务环境。
缺点:
- 不可撤销、不可更改:JWT 一旦签发,在有效期内无法撤销和更改,除非在服务端配置黑名单。但是随之而来又有一个问题便是这个JWT黑名单表存在哪里。存在服务器,那么又要搞多服务器同步。存在关系数据库,那么查数据库效率又低。存在Redis,则又回到了Token丢失问题。
总结
- 由于jwt是无状态的,它一发布开始,就意味着固定了过期时间。我们没法对他做失效,没法实现续期,它的好处也是显而易见的。不需要任何一个中心化的地方去保存它,管理它,查询它,比对它。
双token方案
双 Token 方案主要是为了解决 JWT 的续期问题,因为 JWT 一旦生成,就在设定的有效期内自动生效,服务器无法主动撤销或管理它的有效性。这带来了以下几个问题:
有效期太长的风险:如果 JWT 的有效期设置得过长,那么在这段时间内服务器无法控制用户的状态。如果用户的账户被禁用,或者 Token 被窃取,攻击者可能会在有效期内继续访问系统,造成安全隐患。
有效期太短的用户体验问题:如果 JWT 有效期太短,用户会频繁遇到 Token 过期的情况,要求重新登录,用户体验会大打折扣。
中心化状态管理的违背初衷:如果每次解析 JWT 时还需要去服务器比对用户状态,就违背了 JWT 无状态认证的初衷,也会增加每次请求的延迟。
在双 Token 方案中,分为 Access Token 和 Refresh Token:
Access Token:短期有效,一般有效期设置为 10 分钟,专用于每次请求时的认证。这样即使被盗,风险也被限制在很短的时间内。
Refresh Token:长期有效,通常有效期为 7 天或更长。用于在 Access Token 过期时获取新的 Access Token,不需要用户重新登录。
这里的关键在于,refresh_token申请access_token的时候,用户是无感知的,前后端的框架自动去更新这个新的access_token。
还有一个点在申请access_token的时候,后端这时候会去校验用户的状态等问题,如果发现用户被禁用了,就申请不到token了。
总结
双 Token 方案通过短期的 Access Token 和长期的 Refresh Token 相结合,解决了 JWT 的续期问题。Access Token 短期有效,限制了安全风险;Refresh Token 长期有效,用于无感知续期,提升了用户体验。服务器在续期时可以验证用户状态,确保安全性和控制力,这使得双 Token 成为兼顾安全和体验的理想认证方案。

