看到一篇微信公众号文章:Session、Token、JWT、SSO、OAuth 认证体系详解,里面对于使用过的一些技术概念做了阐释。突然发现 SSO 单点登录的定义是“让用户登录一次就能访问多个相关但独立的系统”,那我之前做的新登录后旧 Token 失效是什么?

问了 chatgpt 给出一份相似功能对比(我的描述词是“用户登录会挤掉其他用户的登录状态”):

功能作用是否会挤掉其他登录
SSO(Single Sign-On,单点登录)一个账号登录多个系统❌ 默认不会
单点注销 SLO(Single Logout)一个系统退出,其他系统一起退出✅ 会
会话互斥登录(Single Session / Kickout)同一个账号只能一个地方在线✅ 会
多端登录控制限制 PC、手机、浏览器数量可配置
Token 吊销新登录后旧 Token 失效✅ 会

最符合我表达意思的是 Token 吊销的功能,那是给小程序和 APP 通讯的时候,有需求针对账号做一个新登录退出所有其他的该账号的登录功能。主要是通过 Laravel 中间件在请求前截取 jwt 内容,判断当前账号如果开启了这个功能并且当前请求的 Token 有效时间如果小于存储的有效时间,就把当前的 Token 给删除掉,只保留最新的一条。登录状态一般是 redis 存储,也有做持久化存储的。

当然这是多端之间的通讯,如果是使用 Session 通讯的前后端不分离的场景下,要求只有一个账号登录,对应的功能就是这里的会话互斥登录功能。多端登录控制 也比较好理解,比如移动端微信搜索框下就有一个已登录设备管理功能,可以管理其他端的登录状态。类似的 ezbookkeeping 做的 设备和会话 功能,就是把所有登录的状态都显示在一个列表,可以主动注销掉其他的登录。按照这个范例,其实之前项目也可以这样做,一目了然哪些设备和会话有在登录。

说到这里,对于什么是 SSO 单点登录功能还是有点迷茫。如果说登录到其他系统就算 SSO,那么 Oauth,还有前公司的微服务架构实现的注册中心也算了。询问了 chatgpt 确认了这一点:

SSO 是一种业务目标/能力,不是一种具体协议。OAuth、CAS、SAML、OIDC 等都是实现 SSO 的技术方案;JWT 则不是 SSO 协议,而通常是 SSO 体系里用于传递身份信息的一种 Token 格式。
方案定位现在使用情况
CAS专门做SSO老企业很多
SAML企业身份联邦大型企业常见
OAuth2授权协议广泛使用
OIDCOAuth+登录现在主流
JWTToken格式经常配合OIDC
Session共享传统SSO方案小型系统

CAS 在前公司的仪器管理系统里遇到过,校内用户通过统一身份认证进行授权登录,实现协议据说就是 CAS。大部分实验室和高校内部系统都支持该协议。

配置CAS认证源 - 腾讯统一身份

OAuth2 是在做一个站点免登录跳转到另一个站点的需求时接触到的。一开始看到 oauth.php 中的 providersconsumers 是懵的,因为跟之前接触过的微信小程序的授权登录不太一样。

翻到调用的原版的 Oauth2.0 三方依赖里,有 server/client 的概念,到了调用层就变成了 providersconsumers。一个站点即是 oauth 服务提供商,又是服务的消费者。所以在 A 站点需要免登录到 B 站点时,给 B 站点配置一个 A 站点的 provider,再给 A 站点配置一个 B 站点的 consumer...因为是互为表里的关系,所以看着有点乱。A 跳转到 B 的时候,携带了 A 站点标识,然后 B 站点 读取 A 站点的 provider,存在就发起 oauth 验证申请。因为是重定向可以直接获取到 A 站点登录用户的信息,返回的 access_token 中也携带了 A 站点用户的 id。之后再通过 access_token 去拿用户信息就简单了。

所以实现的底层调用还是 Oauth2.0,只不过业务上套了一层调用混乱的代码,导致阅读起来有点困难。

微信小程序的授权登录是拿 code 换的 access_token,然后获取到手机号、openId 等信息,之后根据手机号判断系统用户是否存在,有就直接登录,没有就创建账号。其实是差不多的逻辑。

微信手机号授权登录属于 OAuth2 思路的第三方身份认证;App 手机号快捷登录属于运营商身份认证服务;它们都不是 SSO,而是“登录方式/身份提供方”。最终通常都会接入自己的 OAuth2/OIDC 认证中心,再给业务系统签发自己的 Token。

一般的如微信的手机号授权登录跟 App 端的手机号快捷登录还不太一样。

微信小程序手机号快速验证:不是标准 OAuth 2.0 流程,但设计思想类似 OAuth 的授权模式。
App 端手机号快捷登录(运营商一键登录):通常也不是 OAuth 2.0,而是运营商自定义的认证协议。
功能是否 OAuth2本质
微信开放平台登录接近 OAuth2第三方身份认证
微信小程序手机号授权类似 OAuth 授权码手机号身份授权
App 手机号快捷登录通常不是 OAuth2运营商认证
Apple 登录OAuth2 + OIDC标准身份认证
Google 登录OAuth2 + OIDC标准身份认证
企业 SSOOAuth2/OIDC/SAML/CAS统一身份认证

最终结论:

OAuth2 是“授权协议”;OIDC 是“登录协议”;微信手机号授权和运营商快捷登录是“身份认证服务”,借用了 OAuth 的思想,但不是 OAuth2 标准实现。