mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-05-02 20:02:45 +08:00
优化文档SSO集成流程
This commit is contained in:
parent
3eaa6b9baf
commit
e1141ef942
@ -1,5 +1,6 @@
|
|||||||
package com.pj.sso;
|
package com.pj.sso;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.sso.SaSsoManager;
|
||||||
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
|
import cn.dev33.satoken.sso.config.SaSsoClientConfig;
|
||||||
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
|
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
@ -20,10 +21,11 @@ public class SsoClientController {
|
|||||||
// 首页
|
// 首页
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String index() {
|
public String index() {
|
||||||
|
String solUrl = SaSsoManager.getClientConfig().splicingSloUrl();
|
||||||
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
|
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
|
||||||
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
|
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
|
||||||
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a> " +
|
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a> " +
|
||||||
"<a href='/sso/logout?back=self'>注销</a></p>";
|
"<a href=\"javascript:location.href='" + solUrl + "?back=' + encodeURIComponent(location.href);\">注销</a> </p>";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +137,11 @@ public class SsoClientController {
|
|||||||
// 首页
|
// 首页
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String index() {
|
public String index() {
|
||||||
|
String solUrl = SaSsoManager.getClientConfig().splicingSloUrl();
|
||||||
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
|
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
|
||||||
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
|
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
|
||||||
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a> " +
|
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a> " +
|
||||||
"<a href='/sso/logout?back=self'>注销</a></p>";
|
"<a href=\"javascript:location.href='" + solUrl + "?back=' + encodeURIComponent(location.href);\">注销</a> </p>";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,122 +296,8 @@ public class SaSso2ClientApplication {
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
### 5、无刷单点注销
|
|
||||||
|
|
||||||
有了单点登录,就必然伴随着单点注销(一处注销,全端下线)
|
### 5、跨 Redis 的单点登录
|
||||||
|
|
||||||
如果你的所有 client 都是基于 SSO 模式二来对接的,那么单点注销其实很简单:
|
|
||||||
|
|
||||||
``` java
|
|
||||||
// 在 `sa-token.is-share=true` 的情况下,调用此代码即可单点注销:
|
|
||||||
StpUtil.logout();
|
|
||||||
|
|
||||||
// 在 `sa-token.is-share=false` 的情况下,调用此代码即可单点注销:
|
|
||||||
StpUtil.logout(StpUtil.getLoginId());
|
|
||||||
```
|
|
||||||
|
|
||||||
你可能会比较疑惑,这不就是个普通的会话注销API吗,为什么会有单点注销的效果?
|
|
||||||
|
|
||||||
因为模式二需要各个 sso-client 和 sso-server 连接同一个 redis,即使登录再多的 client,本质上对应的仍是同一个会话,因此可以做到任意一处调用注销,全端一起下线的效果。
|
|
||||||
|
|
||||||
而如果你的各个 client 架构各不相同,有的是模式二对接,有的是模式三对接,则需要麻烦一点才能做到单点注销。
|
|
||||||
|
|
||||||
这里的“麻烦”指两处:1、框架内部逻辑麻烦;2、开发者集成麻烦。
|
|
||||||
|
|
||||||
框架内部的麻烦 sa-token-sso 已经封装完毕,无需过多关注,而开发者的麻烦步骤也不是很多:
|
|
||||||
|
|
||||||
|
|
||||||
#### 5.1、增加 pom.xml 配置
|
|
||||||
|
|
||||||
<!---------------------------- tabs:start ---------------------------->
|
|
||||||
<!-------- tab:Maven 方式 -------->
|
|
||||||
``` xml
|
|
||||||
<!-- Http请求工具 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.dtflys.forest</groupId>
|
|
||||||
<artifactId>forest-spring-boot-starter</artifactId>
|
|
||||||
<version>1.5.26</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
<!-------- tab:Gradle 方式 -------->
|
|
||||||
``` gradle
|
|
||||||
// Http请求工具
|
|
||||||
implementation 'com.dtflys.forest:forest-spring-boot-starter:1.5.26'
|
|
||||||
```
|
|
||||||
<!---------------------------- tabs:end ---------------------------->
|
|
||||||
|
|
||||||
Forest 是一个轻量级 http 请求工具,详情参考:[Forest](https://forest.dtflyx.com/)
|
|
||||||
|
|
||||||
因为我们已经在控制台手动打印 url 请求日志了,所以此处 `forest.log-enabled=false` 关闭 Forest 框架自身的日志打印,这不是必须的,你可以将其打开。
|
|
||||||
|
|
||||||
|
|
||||||
#### 5.2、SSO-Client 端新增配置:API调用秘钥
|
|
||||||
|
|
||||||
在 `application.yml` 增加:
|
|
||||||
|
|
||||||
<!---------------------------- tabs:start ---------------------------->
|
|
||||||
<!------------- tab:yaml 风格 ------------->
|
|
||||||
``` yaml
|
|
||||||
sa-token:
|
|
||||||
sign:
|
|
||||||
# API 接口调用秘钥
|
|
||||||
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
|
||||||
|
|
||||||
forest:
|
|
||||||
# 关闭 forest 请求日志打印
|
|
||||||
log-enabled: false
|
|
||||||
```
|
|
||||||
<!------------- tab:properties 风格 ------------->
|
|
||||||
``` properties
|
|
||||||
# 接口调用秘钥
|
|
||||||
sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
|
||||||
|
|
||||||
# 关闭 forest 请求日志打印
|
|
||||||
forest.log-enabled=false
|
|
||||||
```
|
|
||||||
<!---------------------------- tabs:end ---------------------------->
|
|
||||||
|
|
||||||
注意 secretkey 秘钥需要与SSO认证中心的一致
|
|
||||||
|
|
||||||
#### 5.3、SSO-Client 配置 http 请求处理器
|
|
||||||
``` java
|
|
||||||
// 配置SSO相关参数
|
|
||||||
@Autowired
|
|
||||||
private void configSso(SaSsoClientConfig ssoClient) {
|
|
||||||
// 配置Http请求处理器
|
|
||||||
ssoClient.sendHttp = url -> {
|
|
||||||
System.out.println("------ 发起请求:" + url);
|
|
||||||
String resStr = Forest.get(url).executeAsString();
|
|
||||||
System.out.println("------ 请求结果:" + resStr);
|
|
||||||
return resStr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 5.3、启动测试
|
|
||||||
重启项目,依次登录三个 client:
|
|
||||||
- [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/)
|
|
||||||
- [http://sa-sso-client2.com:9001/](http://sa-sso-client2.com:9001/)
|
|
||||||
- [http://sa-sso-client3.com:9001/](http://sa-sso-client3.com:9001/)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
在任意一个 client 里,点击 **`[注销]`** 按钮,即可单点注销成功(打开另外两个client,刷新一下页面,登录态丢失)。
|
|
||||||
|
|
||||||
<!--  -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
PS:这里我们为了方便演示,使用的是超链接跳页面的形式,正式项目中使用 Ajax 调用接口即可做到无刷单点登录退出。
|
|
||||||
|
|
||||||
例如,我们使用 [Apifox 接口测试工具](https://www.apifox.cn/) 可以做到同样的效果:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
测试完毕!
|
|
||||||
|
|
||||||
|
|
||||||
### 6、跨 Redis 的单点登录
|
|
||||||
以上流程解决了跨域模式下的单点登录,但是后端仍然采用了共享Redis来同步会话,如果我们的架构设计中Client端与Server端无法共享Redis,又该怎么完成单点登录?
|
以上流程解决了跨域模式下的单点登录,但是后端仍然采用了共享Redis来同步会话,如果我们的架构设计中Client端与Server端无法共享Redis,又该怎么完成单点登录?
|
||||||
|
|
||||||
这就要采用模式三了,且往下看:[SSO模式三:Http请求获取会话](/sso/sso-type3)
|
这就要采用模式三了,且往下看:[SSO模式三:Http请求获取会话](/sso/sso-type3)
|
||||||
|
@ -22,7 +22,32 @@
|
|||||||
|
|
||||||
### 2、在Client 端更改 Ticket 校验方式
|
### 2、在Client 端更改 Ticket 校验方式
|
||||||
|
|
||||||
在 application.yml 新增配置:
|
|
||||||
|
#### 2.1、增加 pom.xml 配置
|
||||||
|
|
||||||
|
<!---------------------------- tabs:start ---------------------------->
|
||||||
|
<!-------- tab:Maven 方式 -------->
|
||||||
|
``` xml
|
||||||
|
<!-- Http请求工具 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.dtflys.forest</groupId>
|
||||||
|
<artifactId>forest-spring-boot-starter</artifactId>
|
||||||
|
<version>1.5.26</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
<!-------- tab:Gradle 方式 -------->
|
||||||
|
``` gradle
|
||||||
|
// Http请求工具
|
||||||
|
implementation 'com.dtflys.forest:forest-spring-boot-starter:1.5.26'
|
||||||
|
```
|
||||||
|
<!---------------------------- tabs:end ---------------------------->
|
||||||
|
|
||||||
|
Forest 是一个轻量级 http 请求工具,详情参考:[Forest](https://forest.dtflyx.com/)
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.2、SSO-Client 端新增配置:API调用秘钥
|
||||||
|
|
||||||
|
在 `application.yml` 增加:
|
||||||
|
|
||||||
<!---------------------------- tabs:start ---------------------------->
|
<!---------------------------- tabs:start ---------------------------->
|
||||||
<!------------- tab:yaml 风格 ------------->
|
<!------------- tab:yaml 风格 ------------->
|
||||||
@ -31,14 +56,47 @@ sa-token:
|
|||||||
sso-client:
|
sso-client:
|
||||||
# 打开模式三(使用Http请求校验ticket)
|
# 打开模式三(使用Http请求校验ticket)
|
||||||
is-http: true
|
is-http: true
|
||||||
|
sign:
|
||||||
|
# API 接口调用秘钥
|
||||||
|
secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||||
|
|
||||||
|
forest:
|
||||||
|
# 关闭 forest 请求日志打印
|
||||||
|
log-enabled: false
|
||||||
```
|
```
|
||||||
<!------------- tab:properties 风格 ------------->
|
<!------------- tab:properties 风格 ------------->
|
||||||
``` properties
|
``` properties
|
||||||
# 打开模式三(使用Http请求校验ticket)
|
# 打开模式三(使用Http请求校验ticket)
|
||||||
sa-token.sso-client.is-http=true
|
sa-token.sso-client.is-http=true
|
||||||
|
# 接口调用秘钥
|
||||||
|
sa-token.sign.secret-key=kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
|
||||||
|
|
||||||
|
# 关闭 forest 请求日志打印
|
||||||
|
forest.log-enabled=false
|
||||||
```
|
```
|
||||||
<!---------------------------- tabs:end ---------------------------->
|
<!---------------------------- tabs:end ---------------------------->
|
||||||
|
|
||||||
|
因为我们已经在控制台手动打印 url 请求日志了,所以此处 `forest.log-enabled=false` 关闭 Forest 框架自身的日志打印,这不是必须的,你可以将其打开。
|
||||||
|
|
||||||
|
注意 secretkey 秘钥需要与SSO认证中心的一致
|
||||||
|
|
||||||
|
#### 2.3、SSO-Client 配置 http 请求处理器
|
||||||
|
``` java
|
||||||
|
// 配置SSO相关参数
|
||||||
|
@Autowired
|
||||||
|
private void configSso(SaSsoClientConfig ssoClient) {
|
||||||
|
// 配置Http请求处理器
|
||||||
|
ssoClient.sendHttp = url -> {
|
||||||
|
System.out.println("------ 发起请求:" + url);
|
||||||
|
String resStr = Forest.get(url).executeAsString();
|
||||||
|
System.out.println("------ 请求结果:" + resStr);
|
||||||
|
return resStr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.4、测试
|
||||||
|
|
||||||
重启项目,访问测试:
|
重启项目,访问测试:
|
||||||
- [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/)
|
- [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/)
|
||||||
@ -49,6 +107,10 @@ sa-token.sso-client.is-http=true
|
|||||||
> 注:如果已测试运行模式二,可先将Redis中的数据清空,以防旧数据对测试造成干扰
|
> 注:如果已测试运行模式二,可先将Redis中的数据清空,以防旧数据对测试造成干扰
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 3、获取 UserInfo
|
### 3、获取 UserInfo
|
||||||
除了账号id,我们可能还需要将用户的昵称、头像等信息从 Server端 带到 Client端,即:用户资料的拉取。
|
除了账号id,我们可能还需要将用户的昵称、头像等信息从 Server端 带到 Client端,即:用户资料的拉取。
|
||||||
|
|
||||||
@ -192,10 +254,10 @@ public Object getFansList(Long loginId) {
|
|||||||
访问测试:[http://sa-sso-client1.com:9001/sso/myFansList](http://sa-sso-client1.com:9001/sso/myFansList)
|
访问测试:[http://sa-sso-client1.com:9001/sso/myFansList](http://sa-sso-client1.com:9001/sso/myFansList)
|
||||||
|
|
||||||
|
|
||||||
|
### 5、无刷单点注销
|
||||||
|
|
||||||
### 5、单点注销
|
有了单点登录,就必然伴随着单点注销(一处注销,全端下线)
|
||||||
|
|
||||||
有关 SSO 单点注销的步骤,在上一章节的“无刷单点注销”部分已讲解完毕(模式二和模式三通用),所以此处就不再赘述了。
|
|
||||||
|
|
||||||
此处简单介绍一下 SSO 模式三的单点注销链路过程:
|
此处简单介绍一下 SSO 模式三的单点注销链路过程:
|
||||||
|
|
||||||
@ -212,6 +274,44 @@ public Object getFansList(Long loginId) {
|
|||||||
|
|
||||||
这些逻辑 Sa-Token 内部已经封装完毕,你只需按照文档步骤集成即可。
|
这些逻辑 Sa-Token 内部已经封装完毕,你只需按照文档步骤集成即可。
|
||||||
|
|
||||||
|
#### 5.1、更改注销方案
|
||||||
|
|
||||||
|
将 sso-client 首页路由方法里的注销链接换成 `/sso/logout` 接口:
|
||||||
|
``` java
|
||||||
|
// SSO-Client端:首页
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String index() {
|
||||||
|
String str = "<h2>Sa-Token SSO-Client 应用端</h2>" +
|
||||||
|
"<p>当前会话是否登录:" + StpUtil.isLogin() + "</p>" +
|
||||||
|
"<p><a href=\"javascript:location.href='/sso/login?back=' + encodeURIComponent(location.href);\">登录</a>" +
|
||||||
|
" <a href='/sso/logout?back=self'>注销</a></p>";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.2、启动测试
|
||||||
|
重启项目,依次登录三个 client:
|
||||||
|
- [http://sa-sso-client1.com:9001/](http://sa-sso-client1.com:9001/)
|
||||||
|
- [http://sa-sso-client2.com:9001/](http://sa-sso-client2.com:9001/)
|
||||||
|
- [http://sa-sso-client3.com:9001/](http://sa-sso-client3.com:9001/)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在任意一个 client 里,点击 **`[注销]`** 按钮,即可单点注销成功(打开另外两个client,刷新一下页面,登录态丢失)。
|
||||||
|
|
||||||
|
<!--  -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
PS:这里我们为了方便演示,使用的是超链接跳页面的形式,正式项目中使用 Ajax 调用接口即可做到无刷单点登录退出。
|
||||||
|
|
||||||
|
例如,我们使用 [Apifox 接口测试工具](https://www.apifox.cn/) 可以做到同样的效果:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
测试完毕!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 6、后记
|
### 6、后记
|
||||||
当我们熟读三种模式的单点登录之后,其实不难发现:所谓单点登录,其本质就是多个系统之间的会话共享。
|
当我们熟读三种模式的单点登录之后,其实不难发现:所谓单点登录,其本质就是多个系统之间的会话共享。
|
||||||
|
Loading…
Reference in New Issue
Block a user