用户认证中的有状态和无状态

引言#

我们在系统设计的时候,用户的认证是最基本也是最重要的功能了。我们常见的方案,就是将用户的认证信息保存到 session 里面。由于近年来微服务的快速兴起,一种 JWT 的认证方式出现在了大众的眼中。在单体服务的时代,很多系统设计的都是有状态的服务。随着微服务的出现,大多数系统设计的时候,都开始考虑无状态服务了。那它们的唯一区别,就是服务端是否会保存客户端的信息。简而言之,服务端保存了客户端的信息的这种状态的服务,就被称为有状态的服务,反之,就是无状态服务了。

有状态#

有状态常见的模型就是 cookie - session 模型,这里就以 cookie - seesion 为例来说明有状态服务。

用户认证过程#

1、客户端向服务端发起请求。
2、在第一次客户端发起请求的时候,服务端会创建一个 Key 为 session-id 的值,并保存在服务端同时写入到客户端的 cookie 中。
3、之后客户端的每次请求,都会将 cookie 信息发送给服务端,服务端会根据 cookie 进行判断。

优点#

1、客户端的信息都保存在服务端,如果将客户端的认证信息删除,那么只需要将对应的 session 信息删除即可。

缺点#

1、当用户量特别大的时候,服务端需要保存大量的 session 信息,会耗费大量的资源。
2、如果在服务端集群的情况下,session 的信息不能共享。
3、cookie 有同源策略和跨域限制,部分业务场景下 cookie 不能传递。
4、有些浏览器不支持 cookie 或禁用 cookie,部分手机浏览器不支持 cookie。

应用场景#

如果以集群式的方式部署多台服务,可以使用以下策略:

1、配置负载均衡的路由策略为 hash 一致性算法,这种方式如何某个服务停了,那么会重新分配到新的机器,就又需要重新登录认证。(这种方式不推荐使用)
2、分布式 session 方式,这种方式可以将 session 保存到 redis 或者数据库中,提供给多个服务使用,实现 session 的集中管理。

如果有多个服务需要共享登录认证信息,可以使用 SSO 单点服务。

无状态#

无状态的认证,服务端在验证客户端发送过来的请求信息之后,服务端根据一定的算法生成一个 Token 令牌返回给客户端。
客户端之后的每次请求都需要携带 Token 令牌,服务端接收到 Token 令牌之后进行校验,验证通过之后提取令牌中信息来识别用户。

无状态用户认证过程#

1、客户端执行登录操作,发送账号密码等信息。
2、服务端校验客户端的用户信息,根据对应的用户信息和服务端密钥生成 Token 令牌,然后返回给客户端。
3、客户端在收到 Token 令牌之后,将其保存到本地的 LocalStorage。
4、以后的每次客户端发起请求时,都携带 Token 令牌。
5、服务端收到 Token 令牌之后,验证 Token 令牌的有效性和时效性,之后根据密钥解密参数信息。

优点#

1、服务端不需要保留客户端的任何信息,每次只需要通过特定的算法进行校验,节省了大量的存储空间。
2、方便水平扩容,不需要 SSO 服务,只要保证新的服务采用同样的验证算法,就可以获得对应的信息。

缺点#

1、当客户端的 Token 令牌被盗用,或者需要手动封禁某个用户的时候,无法对 Token 令牌进行操作,需要等到 Token 令牌失效。
2、如果在服务端维护一个 Token 令牌和用户的关系,又违背了无状态服务设计的理念。

应用场景#

1、生成的 Token 令牌中携带用户的常用信息,不携带用户的敏感信息,例如:密码、手机号等,这些信息可以通过 BASE 64 解析处理。
2、要处理服务端主动禁用某个 Token 令牌,可以使用黑名单机制,每次请求前都判断当前 Token 令牌是否已经被写入黑名单。
3、Token 令牌中信息处理基本信息之外,还需要携带,例如:签发时间、有效时间、刷新 Token 令牌等字段,用来处理 Token 令牌刷新过期时间。

总结#

在实际的系统设计中,需要充分理解需求,合理的使用技术,不同的技术方案适用不同的场景,技术存在即合理。

其他#

1、目前大部分的互联网的产品中使用 JWT 的认证方式居多。
2、在一些企业内部的管理系统中采用 cookie - session 的居多。

posted @   Yxh_blogs  阅读(1101)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2018-04-06 Go中函数作为值、类型传递。
2015-04-06 有两种分别用<bgsound>和<embed></embed>标签,当用<embed>插入背景音乐时可以设置宽度和高度为0,隐藏播放器。
点击右上角即可分享
微信分享提示
CONTENTS