完善文档:Session模型详解

This commit is contained in:
click33 2021-07-22 04:22:59 +08:00
parent cbc28d392b
commit 95beaee6ee
7 changed files with 105 additions and 22 deletions

View File

@ -11,7 +11,7 @@
- [权限认证](/use/jur-auth)
- [踢人下线](/use/kick)
- [注解式鉴权](/use/at-check)
- [路由拦截鉴权](/use/route-check)
- [路由拦截鉴权](/use/route-check)
- [Session会话](/use/session)
- [框架配置](/use/config)

View File

@ -1,11 +1,93 @@
# Session模型详解
# Sa-Token 中的 Session会话 模型详解
---
在`Sa-Token`中, `Session` 分为三种, 分别是:
- `User-Session`: 指的是框架为每个`loginId`分配的`Session`
- `Token-Session`: 指的是框架为每个`token`分配的`Session`
- `自定义Session`: 指的是以一个`特定的值`作为SessionId来分配的`Session`
### 1、User-Session
提起Session你脑海中最先浮现的可能就是 JSP 中的 HttpSession它的工作原理可以大致总结为
客户端每次与服务器第一次握手时,会被强制分配一个 `[唯一id]` 作为身份标识,注入到 Cookie 之中,
之后每次发起请求时,客户端都要将它提交到后台,服务器根据 `[唯一id]` 找到每个请求专属的Session对象维持会话
这种机制简单粗暴却有N多明显的缺点
1. 同一账号分别在PC、APP登录会被识别为两个不相干的会话
2. 一个设备难以同时登录两个账号
3. 每次一个新的客户端访问服务器时都会产生一个新的Session对象即使这个客户端只访问了一次页面
4. 在不支持Cookie的客户端下这种机制会失效
Sa-Token Session可以理解为 HttpSession 的升级版:
1. Sa-Token只在调用`StpUtil.login(id)`登录会话时才会产生Session不会为每个陌生会话都产生Session节省性能
2. 在登录时产生的Session是分配给账号id的而不是分配给指定客户端的也就是说在PC、APP上登录的同一账号所得到的Session也是同一个所以两端可以非常轻松的同步数据
3. Sa-Token支持Cookie、Header、body三个途径提交Token而不是仅限于Cookie
4. 由于不强依赖Cookie所以只要将Token存储到不同的地方便可以做到一个客户端同时登录多个账号
这种为账号id分配的Session我们给它起一个合适的名字`User-Session`,你可以通过如下方式操作它:
``` java
// 获取当前会话的 User-Session
SaSession session = StpUtil.getSession();
// 从 User-Session 中读取、写入数据
session.get("name");
session.set("name", "张三");
```
使用`User-Session`在不同端同步数据是非常方便的,因为只要 PC 和 APP 登录的账号id一致它们对应的都是同一个Session
举个应用场景在PC端点赞的帖子列表在APP端的点赞记录里也要同步显示出来
### 2、Token-Session
随着业务推进,我们还可能会遇到一些需要数据隔离的场景:
> 指定客户端超过两小时无操作就自动下线,如果两小时内有操作,就再续期两小时,直到新的两小时无操作
那么这种请求访问记录应该存储在哪里呢?放在 User-Session 里吗?
可别忘了PC端和APP端可是共享的同一个 User-Session ,如果把数据放在这里,
那就意味着即使用户在PC端一直无操作只要手机上用户还在不间断的操作那PC端也不会过期
解决这个问题的关键在于虽然两个设备登录的是同一账号但是两个它们得到的token是不一样的
Sa-Token针对会话登录不仅为账号id分配了`User-Session`同时还为每个token分配了不同的`Token-Session`
不同的设备端哪怕登录了同一账号只要它们得到的token不一致它们对应的 `Token-Session` 就不一致,这就为我们不同端的独立数据读写提供了支持:
``` java
// 获取当前会话的 Token-Session
SaSession session = StpUtil.getTokenSession();
// 从 Token-Session 中读取、写入数据
session.get("name");
session.set("name", "张三");
```
### 3、Custom-Session
除了以上两种SessionSa-Token还提供了第三种Session那就是`Custom-Session`你可以将其理解为自定义Session
Custom-Session不依赖特定的 账号id 或者 token而是依赖于你提供的SessionId
``` java
// 获取指定key的 Custom-Session
SaSession session = SaSessionCustomUtil.getSessionById("goods-10001");
// 从 Custom-Session 中读取、写入数据
session.get("name");
session.set("name", "张三");
```
只要两个自定义Session的Id一致它们就是同一个Session
### 4、Session模型结构图
三种Session创建时机
- `User-Session`: 指的是框架为每个 账号id 分配的 Session
- `Token-Session`: 指的是框架为每个 token 分配的 Session
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId来分配的 Session
**假设三个客户端登录同一账号且配置了不共享token那么此时的Session模型是**
@ -15,7 +97,7 @@
简而言之:
- `Token-Session` 以token为主只要token不同那么对应的Session对象就不同
- `User-Session` 以UserId为主只要token指向的UserId一致那么对应的Session对象就一致
- `自定义Session` 以特定的key为主不同key对应不同的Session对象
- `Custom-Session` 以特定的key为主不同key对应不同的Session对象

View File

@ -103,9 +103,9 @@
var footer = [
'<br/><br/><br/><br/><br/><br/><br/><hr/>',
'<footer>',
'<span>发现错误? 在 <a href="' + url + '" target="_blank">Gitee</a><a href="' + url2 +
'<span>发现错误? 您可以<a href="' + url + '" target="_blank">Gitee</a><a href="' + url2 +
'" target="_blank">GitHub</a> 帮助我们完善此页文档!</span>',
'<a href="https://jq.qq.com/?_wv=1027&k=45H977HM" target="_blank">点我加入QQ群</a>交流反馈',
'<a href="https://jq.qq.com/?_wv=1027&k=45H977HM" target="_blank">加入QQ群</a> 交流反馈',
'</footer>'
].join('');
return html + footer;

View File

@ -26,7 +26,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
// 注册Sa-Token的注解拦截器打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关)
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关)
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
}
}

View File

@ -6,10 +6,10 @@
### 方式1、在`application.yml`配置
### 方式1、在 application.yml 配置
``` java
# Sa-Token配置
# Sa-Token 配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
@ -110,7 +110,7 @@ PS两者的区别在于**`方式1会覆盖yml中的配置方式2会与y
配置示例:
``` yml
# sa-token配置
# Sa-Token 配置
sa-token:
# SSO-相关配置
sso:
@ -135,7 +135,7 @@ sa-token:
配置示例:
``` yml
# sa-token配置
# Sa-Token 配置
sa-token:
token-name: satoken-server
# OAuth2.0 配置

View File

@ -1,4 +1,4 @@
# 路由拦截鉴权
# 路由拦截鉴权
---
假设我们有如下需求:
@ -14,10 +14,10 @@
``` java
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
// 注册Sa-Token的登录拦截器
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册登录拦截器,并排除登录接口或其他可匿名访问的接口地址 (与注解拦截器无关)
// 注册Sa-Token的路由拦截器,并排除登录接口或其他可匿名访问的接口地址 (与注解拦截器无关)
registry.addInterceptor(new SaRouteInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/doLogin");
}
}

View File

@ -3,11 +3,12 @@
### Session是什么
Session是会话中专业的数据缓存组件通过`Session`我们可以很方便的缓存一些高频读写数据,提高程序性能<br>
在`Sa-Token`中, `Session` 分为三种, 分别是:
- `User-Session`: 指的是框架为每个`loginId`分配的`Session`
- `Token-Session`: 指的是框架为每个`token`分配的`Session`
- `自定义Session`: 指的是以一个`特定的值`作为SessionId来分配的`Session`
Session是会话中专业的数据缓存组件通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能<br>
在 Sa-Token 中Session 分为三种,分别是:
- `User-Session`: 指的是框架为每个 账号id 分配的 Session
- `Token-Session`: 指的是框架为每个 token 分配的 Session
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId来分配的 Session
> 有关User-Session与Token-Session的详细区别请参考[Session模型详解](/fun/session-model)