# SSO模式二 URL重定向传播会话 如果我们的多个系统:部署在不同的域名之下,但是后端可以连接同一个Redis,那么便可以使用 **`[URL重定向传播会话]`** 的方式做到单点登录。 ### 1、设计思路 首先我们再次复习一下,多个系统之间为什么无法同步登录状态? 1. 前端的`Token`无法在多个系统下共享。 2. 后端的`Session`无法在多个系统间共享。 关于第二点,我们已在 "SSO模式一" 章节中阐述,使用 [Alone独立Redis插件](/plugin/alone-redis) 做到权限缓存直连 SSO-Redis 数据中心,在此不再赘述。 而第一点,才是我们解决问题的关键所在,在跨域模式下,意味着 "共享Cookie方案" 的失效,我们必须采用一种新的方案来传递Token。 1. 用户在 子系统 点击 `[登录]` 按钮。 2. 用户跳转到子系统登录接口 `/sso/login`,并携带 `back参数` 记录初始页面URL。 - 形如:`http://{sso-client}/sso/login?back=xxx` 3. 子系统检测到此用户尚未登录,再次将其重定向至SSO认证中心,并携带`redirect参数`记录子系统的登录页URL。 - 形如:`http://{sso-server}/sso/auth?redirect=xxx?back=xxx` 4. 用户进入了 SSO认证中心 的登录页面,开始登录。 5. 用户 输入账号密码 并 登录成功,SSO认证中心再次将用户重定向至子系统的登录接口`/sso/login`,并携带`ticket码`参数。 - 形如:`http://{sso-client}/sso/login?back=xxx&ticket=xxxxxxxxx` 6. 子系统根据 `ticket码` 从 `SSO-Redis` 中获取账号id,并在子系统登录此账号会话。 7. 子系统将用户再次重定向至最初始的 `back` 页面。 整个过程,除了第四步用户在SSO认证中心登录时会被打断,其余过程均是自动化的,当用户在另一个子系统再次点击`[登录]`按钮,由于此用户在SSO认证中心已有会话存在, 所以第四步也将自动化,也就是单点登录的最终目的 —— 一次登录,处处通行。 下面我们按照步骤依次完成上述过程: ### 2、准备工作 首先修改hosts文件`(C:\windows\system32\drivers\etc\hosts)`,添加以下IP映射,方便我们进行测试: ``` url 127.0.0.1 sa-sso-server.com 127.0.0.1 sa-sso-client1.com 127.0.0.1 sa-sso-client2.com 127.0.0.1 sa-sso-client3.com ``` ### 3、搭建 Client 端项目 > [!TIP| label:demo | style:callout] > 搭建示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso2-client/`,如遇到难点可结合源码进行测试学习 #### 3.1、去除 SSO-Server 的 Cookie 作用域配置 在SSO模式一章节中我们打开了配置: ``` yaml sa-token: cookie: # 配置 Cookie 作用域 domain: stp.com ``` ``` properties # 配置 Cookie 作用域 sa-token.cookie.domain=stp.com ``` 此为模式一专属配置,现在我们将其注释掉**(一定要注释掉!)** #### 3.2、创建 SSO-Client 端项目 创建一个 SpringBoot 项目 `sa-token-demo-sso2-client`,引入依赖: ``` xml cn.dev33 sa-token-spring-boot-starter ${sa.top.version} cn.dev33 sa-token-sso ${sa.top.version} cn.dev33 sa-token-redis-jackson ${sa.top.version} org.apache.commons commons-pool2 cn.dev33 sa-token-alone-redis ${sa.top.version} ``` ``` gradle // Sa-Token 权限认证,在线文档:https://sa-token.cc implementation 'cn.dev33:sa-token-spring-boot-starter:${sa.top.version}' // Sa-Token 插件:整合SSO implementation 'cn.dev33:sa-token-sso:${sa.top.version}' // Sa-Token 整合 Redis (使用 jackson 序列化方式) implementation 'cn.dev33:sa-token-redis-jackson:${sa.top.version}' implementation 'org.apache.commons:commons-pool2' // Sa-Token插件:权限缓存与业务缓存分离 implementation 'cn.dev33:sa-token-alone-redis:${sa.top.version}' ``` #### 3.3、创建 SSO-Client 端认证接口 同 SSO-Server 一样,Sa-Token 为 SSO-Client 端所需代码也提供了完整的封装,你只需提供一个访问入口,接入 Sa-Token 的方法即可。 ``` java /** * Sa-Token-SSO Client端 Controller */ @RestController public class SsoClientController { // 首页 @RequestMapping("/") public String index() { String solUrl = SaSsoManager.getClientConfig().splicingSloUrl(); String str = "

Sa-Token SSO-Client 应用端

" + "

当前会话是否登录:" + StpUtil.isLogin() + "

" + "

登录 " + " 下载官方示例,依次运行: > - `/sa-token-demo/sa-token-demo-sso2-server/` > - `/sa-token-demo/sa-token-demo-sso2-client/` > > 然后访问: > - [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/) ![sso-server-login-hua](https://oss.dev33.cn/sa-token/doc/sso/sso-server-login-hua.png 's-w-sh') 默认测试密码:`sa / 123456`,其余流程保持不变 --> ### 5、跨 Redis 的单点登录 以上流程解决了跨域模式下的单点登录,但是后端仍然采用了共享Redis来同步会话,如果我们的架构设计中Client端与Server端无法共享Redis,又该怎么完成单点登录? 这就要采用模式三了,且往下看:[SSO模式三:Http请求获取会话](/sso/sso-type3)