Skip to content

单点登录是怎么实现的? ​

用户在认证中心登录一次,多个应用信任这张票,不必各自再收一次密码。前端负责跳转和保存本应用的会话,认证中心负责签发和校验。前端不能自己宣布「已经登录」。

原理 ​

常见流程:

  1. 应用发现没有会话,把用户带到认证中心,并带上自己的回调地址。
  2. 认证中心登录成功后,重定向回应用,并附上一次性授权码。
  3. 应用的服务器用授权码向认证中心换令牌,再给浏览器建立自己的会话。

授权码不要留在浏览器里当长期凭证。回调地址必须事先登记,否则会被人换成攻击者的地址把授权码带走。

同父域的多个子站可以把会话 Cookie 写在父域。这只在你控制这些子域时成立,而且要收紧 Path、Secure 和 SameSite。完全不同的主域不能共享这块 Cookie,必须走上面的跳转。

退出要通知认证中心,并尽量让其他应用的会话失效。只清当前站点的 localStorage,别的标签页和别的应用还是登录的。

追问 ​

和 OAuth、JWT 的关系?

OAuth 描述授权码怎么发、怎么换。JWT 可以是换回来的令牌格式。单点登录是「一次认证、多个应用」的产品流程,可以用这套协议实现。见 JWT。

前端为什么不直接向认证中心换令牌?

换令牌需要客户端密钥,密钥不能放进页面。这一步放在应用自己的服务器上。公开客户端有另外的约束(PKCE),面试里说明密钥不进浏览器即可。

易错点 ​

  • 把密码或长期令牌放进 URL。授权码可以出现在回调里,但只能用一次、寿命很短。
  • 不校验回调里的 state,用户可能被带到攻击者发起的登录流程里。
  • 只在一个前端项目里清登录态,就说已经单点退出。

相关 ​