# SSO模式一 共享Cookie同步会话 如果我们的多个系统可以做到:前端同域、后端同Redis,那么便可以使用 **`[共享Cookie同步会话]`** 的方式做到单点登录。 --- ### 1、设计思路 首先我们分析一下多个系统之间,为什么无法同步登录状态? 1. 前端的 `Token` 无法在多个系统下共享。 2. 后端的 `Session` 无法在多个系统间共享。 所以单点登录第一招,就是对症下药: 1. 使用 `共享Cookie` 来解决 Token 共享问题。 2. 使用 `Redis` 来解决 Session 共享问题。 所谓共享Cookie,就是主域名Cookie在二级域名下的共享,举个例子:写在父域名`stp.com`下的Cookie,在`s1.stp.com`、`s2.stp.com`等子域名都是可以共享访问的。 而共享Redis,并不需要我们把所有项目的数据都放在同一个Redis中,Sa-Token提供了 **[权限缓存与业务缓存分离]** 的解决方案,详情戳:[Alone独立Redis插件](/plugin/alone-redis)。 OK,所有理论就绪,下面开始实战: ### 2、准备工作 首先修改hosts文件`(C:\windows\system32\drivers\etc\hosts)`,添加以下IP映射,方便我们进行测试: ``` url 127.0.0.1 sso.stp.com 127.0.0.1 s1.stp.com 127.0.0.1 s2.stp.com 127.0.0.1 s3.stp.com ``` 其中:`sso.stp.com`为统一认证中心地址,当用户在其它 Client 端发起登录请求时,均将其重定向至认证中心,待到登录成功之后再原路返回到 Client 端。 ### 3、指定Cookie的作用域 在`sso.stp.com`访问服务器,其Cookie也只能写入到`sso.stp.com`下,为了将Cookie写入到其父级域名`stp.com`下,我们需要更改 SSO-Server 端的 yml 配置: ``` yaml sa-token: cookie: # 配置 Cookie 作用域 domain: stp.com ``` ``` properties # 配置 Cookie 作用域 sa-token.cookie.domain=stp.com ``` 这个配置原本是被注释掉的,现在将其打开。另外我们格外需要注意: 在SSO模式一测试完毕之后,一定要将这个配置再次注释掉,因为模式一与模式二三使用不同的授权流程,这行配置会影响到我们模式二和模式三的正常运行。 ### 4、搭建 Client 端项目 > 搭建示例在官方仓库的 `/sa-token-demo/sa-token-demo-sso/sa-token-demo-sso1-client/`,如遇到难点可结合源码进行测试学习。 #### 4.1、引入依赖 新建项目 sa-token-demo-sso1-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}' ``` #### 4.2、新建 Controller 控制器 ``` java /** * Sa-Token-SSO Client端 Controller * @author click33 */ @RestController public class SsoClientController { // SSO-Client端:首页 @RequestMapping("/") public String index() { String authUrl = SaSsoManager.getClientConfig().splicingAuthUrl(); String solUrl = SaSsoManager.getClientConfig().splicingSloUrl(); String str = "

Sa-Token SSO-Client 应用端

" + "

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

" + "

登录 " + " [!TIP| style:callout] > 所有子系统的域名,必须同属一个父级域名 如果我们的子系统在完全不同的域名下,我们又该怎么完成单点登录功能呢? 且往下看,[SSO模式二:URL重定向传播会话](/sso/sso-type2)