前言
最近在对基于 token 做身份认证的项目中扩展 sso
北京
项目大致架构如下
其中服务器端是 RESTful 风格的 API 服务器, 客户端基于 vue 开发的 SPA
身份认证是基于 token, 客户端登录之后, 服务器端验证并发送 JWT token 给客户端, 客户端将 token 存入 localStorage 中并每次恢复到 Vuex 中, 客户端每次请求都会在 HTTP 自定义头部中附带 token
本文简述下我对 OIDC 解决方案的简单理解以及基于上述架构实现 sso 的思路
正文
OIDC 的官方解释如下
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
也就是 OAuth2.0 只解决了资源的访问和分享, OIDC 则基于此实现了用户的认证它的主要目的是提供一次登录, 多个站点享有登录状态也就是当用户在某一使用 OIDC 的网站登录时, 用户被重定向到 OpenID 站点登录, 然后重定向回原来网站
OIDC 已经有很多的企业在使用, 比如 Google 的账号认证授权体系, Microsoft 的账号体系也部署了 OIDC, 当然这些企业有的也是 OIDC 背后的推动者
OIDC 到底怎么运行的
第一期先从简, 也不讨论什么 OIDC 协议族, 就单单说一下 OIDC 是怎么运作的以还是以午安网举例
如果我要使用大午安账号登入午安空间网站, 那么这个大致流程如下:
使用 Implicit Flow
首先午安空间会发送授权请求给 oidc-server
如果已经登录了, oidc-server 会返回一个证件或者如果你没登录会要求你登录, 然后询问你是否授权给午安空间某些权限比如邮件地址等 (当然午安这个例子里面不存在, 因为肯定都是全权限)
一旦你确定并授权了这次登录, oidc-server 会发送 Acess-Token 和 ID Token(如果要求了), 并跳转回午安空间网站 (可以通过 url 附带)
然后午安空间就可以通过之前得到的 ID Token 或者 Access-Token 去访问 oidc-server 获取用户信息了
午安网实现 SSO 的全流程设计
设计可能比较粗糙或者有问题, 如果有问题希望评论一下帮我修正修正 设计使用的是 Implicit Flow
单点登录
主动登出
没啥好说的, 客户端清理自己的状态, 然后发出登出请求给 oidc-server
被动登出
这块就找到了一个网上的例子
其利用 oipc 协议族里的 Discovery 服务中提供的一个 check_session_iframe 接口
核心原理是让客户端插入一个 oidc-server 页面的 iframe 并周期性的检查, 当我在午安空间点击登出的时候, 会发出登出请求给 oidc-server 并触发 oidc-server 的站点清理自己的 cookie, 然后在之前客户端中使用 check_session_iframe 这个隐藏的 iframe 可以检测到这种变化, 从而使得客户端可以得知用户已在再其他的应用的客户端退出登录, 这时候就清理自己客户端的登录状态
例子中的客户端代码
后记
这部分放的是下版本要加的或者完善的
了解下 Authorization Code Flow
自动登录补充
如果只有上面的解决方案的话会存在一个问题, 那就是如果我 sso 已登录, 我到另一个网站比如午安影视, 我需要点击登入之后才会出现登录状态也就是说没有自动登录
一个实现的方法是可以在一开始就去访问 oidc-server 询问是否已经登录, oidc-server 的协议族 Discovery 提供一个接口
来源: https://juejin.im/post/5a96368a6fb9a0633531dc9a