diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index 0634d4e2..12b70e37 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -11,7 +11,7 @@ - [权限认证](/use/jur-auth) - [踢人下线](/use/kick) - [注解式鉴权](/use/at-check) - - [路由拦截式鉴权](/use/route-check) + - [路由拦截鉴权](/use/route-check) - [Session会话](/use/session) - [框架配置](/use/config) diff --git a/sa-token-doc/doc/fun/session-model.md b/sa-token-doc/doc/fun/session-model.md index eb73fccb..e94e256e 100644 --- a/sa-token-doc/doc/fun/session-model.md +++ b/sa-token-doc/doc/fun/session-model.md @@ -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 + +除了以上两种Session,Sa-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对象 diff --git a/sa-token-doc/doc/index.html b/sa-token-doc/doc/index.html index b594fba8..d07812fb 100644 --- a/sa-token-doc/doc/index.html +++ b/sa-token-doc/doc/index.html @@ -103,9 +103,9 @@ var footer = [ '







', '' ].join(''); return html + footer; diff --git a/sa-token-doc/doc/use/at-check.md b/sa-token-doc/doc/use/at-check.md index 6b3ad0fb..8444b4a6 100644 --- a/sa-token-doc/doc/use/at-check.md +++ b/sa-token-doc/doc/use/at-check.md @@ -26,7 +26,7 @@ public class SaTokenConfigure implements WebMvcConfigurer { // 注册Sa-Token的注解拦截器,打开注解式鉴权功能 @Override public void addInterceptors(InterceptorRegistry registry) { - // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关) + // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关) registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**"); } } diff --git a/sa-token-doc/doc/use/config.md b/sa-token-doc/doc/use/config.md index 7a91342f..e375dd8e 100644 --- a/sa-token-doc/doc/use/config.md +++ b/sa-token-doc/doc/use/config.md @@ -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 配置 diff --git a/sa-token-doc/doc/use/route-check.md b/sa-token-doc/doc/use/route-check.md index 1a33970c..6270d41f 100644 --- a/sa-token-doc/doc/use/route-check.md +++ b/sa-token-doc/doc/use/route-check.md @@ -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"); } } diff --git a/sa-token-doc/doc/use/session.md b/sa-token-doc/doc/use/session.md index 7a5fb88f..c4b34352 100644 --- a/sa-token-doc/doc/use/session.md +++ b/sa-token-doc/doc/use/session.md @@ -3,11 +3,12 @@ ### Session是什么? -Session是会话中专业的数据缓存组件,通过`Session`我们可以很方便的缓存一些高频读写数据,提高程序性能
-在`Sa-Token`中, `Session` 分为三种, 分别是: -- `User-Session`: 指的是框架为每个`loginId`分配的`Session` -- `Token-Session`: 指的是框架为每个`token`分配的`Session` -- `自定义Session`: 指的是以一个`特定的值`作为SessionId,来分配的`Session` +Session是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能
+在 Sa-Token 中,Session 分为三种,分别是: + +- `User-Session`: 指的是框架为每个 账号id 分配的 Session +- `Token-Session`: 指的是框架为每个 token 分配的 Session +- `Custom-Session`: 指的是以一个 特定的值 作为SessionId,来分配的 Session > 有关User-Session与Token-Session的详细区别,请参考:[Session模型详解](/fun/session-model)