重构概念:User-Session -> Account-Session

This commit is contained in:
click33
2023-05-15 18:23:18 +08:00
parent d6037878e8
commit aaa26a4c58
18 changed files with 1247 additions and 2054 deletions

View File

@@ -13,7 +13,7 @@ package cn.dev33.satoken.stp;
* "loginId": "10001", // 此token对应的LoginId未登录时为null
* "loginType": "login", // 账号类型标识
* "tokenTimeout": 2591977, // token剩余有效期 (单位: 秒)
* "sessionTimeout": 2591977, // User-Session剩余有效时间 (单位: 秒)
* "sessionTimeout": 2591977, // Account-Session剩余有效时间 (单位: 秒)
* "tokenSessionTimeout": -2, // Token-Session剩余有效时间 (单位: 秒) (-2表示系统中不存在这个缓存)
* "tokenActivityTimeout": -1, // token剩余无操作有效时间 (单位: 秒)
* "loginDevice": "default-device" // 登录设备类型

View File

@@ -112,7 +112,7 @@ public class LoginAuthController {
System.out.println("当前登录客户端的设备类型:" + info.getLoginDevice());
System.out.println("当前 Token 的剩余有效期:" + info.getTokenTimeout()); // 单位:秒,-1代表永久有效-2代表值不存在
System.out.println("当前 Token 的剩余临时有效期:" + info.getTokenActivityTimeout()); // 单位:秒,-1代表永久有效-2代表值不存在
System.out.println("当前 User-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效-2代表值不存在
System.out.println("当前 Account-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效-2代表值不存在
System.out.println("当前 Token-Session 的剩余有效期" + info.getTokenSessionTimeout()); // 单位:秒,-1代表永久有效-2代表值不存在
// 返回给前端

View File

@@ -6,6 +6,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.pj.satoken.StpUserUtil;
/**
* 登录认证(User版):只有登录之后才能进入该方法

View File

@@ -5,6 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.pj.satoken.StpUserUtil;
import org.springframework.core.annotation.AliasFor;
import cn.dev33.satoken.annotation.SaCheckPermission;

View File

@@ -5,6 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.pj.satoken.StpUserUtil;
import org.springframework.core.annotation.AliasFor;
import cn.dev33.satoken.annotation.SaCheckRole;

View File

@@ -1,11 +1,10 @@
package com.pj;
import cn.dev33.satoken.SaManager;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
import cn.dev33.satoken.SaManager;
/**
* sa-token整合 solon 示例
* @author noear

View File

@@ -72,7 +72,7 @@ StpUtil.getExtra(token, key); // 获取指定 Token 的扩展信息(此函
### 5、Session 相关
``` java
// User-Session 相关
// Account-Session 相关
StpUtil.getSession(); // 获取当前会话的Session如果Session尚未创建则新建并返回
StpUtil.getSession(true); // 获取当前会话的Session, 如果Session尚未创建isCreate=是否新建并返回
StpUtil.getSessionByLoginId(10001); // 获取指定账号id的Session如果Session尚未创建则新建并返回
@@ -97,7 +97,7 @@ StpUtil.updateLastActivityToNow(); // 续签当前token(将 [最后操作
// 长久有效期
StpUtil.getTokenTimeout(); // 获取当前登录者的 token 剩余有效时间 (单位: 秒)
StpUtil.getSessionTimeout(); // 获取当前登录者的 User-Session 剩余有效时间 (单位: 秒)
StpUtil.getSessionTimeout(); // 获取当前登录者的 Account-Session 剩余有效时间 (单位: 秒)
StpUtil.getTokenSessionTimeout(); // 获取当前 Token-Session 剩余有效时间 (单位: 秒)
StpUtil.renewTimeout(timeout); // 对当前 Token 的 timeout 值进行续期
StpUtil.renewTimeout(token, timeout); // 对指定 Token 的 timeout 值进行续期

View File

@@ -2,7 +2,7 @@
---
### 1、User-Session
### 1、Account-Session
提起Session你脑海中最先浮现的可能就是 JSP 中的 HttpSession它的工作原理可以大致总结为
@@ -24,17 +24,17 @@ Sa-Token Session可以理解为 HttpSession 的升级版:
3. Sa-Token支持Cookie、Header、body三个途径提交Token而不是仅限于Cookie
4. 由于不强依赖Cookie所以只要将Token存储到不同的地方便可以做到一个客户端同时登录多个账号
这种为账号id分配的Session我们给它起一个合适的名字`User-Session`,你可以通过如下方式操作它:
这种为账号id分配的Session我们给它起一个合适的名字`Account-Session`,你可以通过如下方式操作它:
``` java
// 获取当前会话的 User-Session
// 获取当前会话的 Account-Session
SaSession session = StpUtil.getSession();
// 从 User-Session 中读取、写入数据
// 从 Account-Session 中读取、写入数据
session.get("name");
session.set("name", "张三");
```
使用`User-Session`在不同端同步数据是非常方便的,因为只要 PC 和 APP 登录的账号id一致它们对应的都是同一个Session
使用`Account-Session`在不同端同步数据是非常方便的,因为只要 PC 和 APP 登录的账号id一致它们对应的都是同一个Session
举个应用场景在PC端点赞的帖子列表在APP端的点赞记录里也要同步显示出来
@@ -44,13 +44,13 @@ session.set("name", "张三");
> 指定客户端超过两小时无操作就自动下线,如果两小时内有操作,就再续期两小时,直到新的两小时无操作
那么这种请求访问记录应该存储在哪里呢?放在 User-Session 里吗?
那么这种请求访问记录应该存储在哪里呢?放在 Account-Session 里吗?
可别忘了PC端和APP端可是共享的同一个 User-Session ,如果把数据放在这里,
可别忘了PC端和APP端可是共享的同一个 Account-Session ,如果把数据放在这里,
那就意味着即使用户在PC端一直无操作只要手机上用户还在不间断的操作那PC端也不会过期
解决这个问题的关键在于虽然两个设备登录的是同一账号但是两个它们得到的token是不一样的
Sa-Token针对会话登录不仅为账号id分配了`User-Session`同时还为每个token分配了不同的`Token-Session`
Sa-Token针对会话登录不仅为账号id分配了`Account-Session`同时还为每个token分配了不同的`Token-Session`
不同的设备端哪怕登录了同一账号只要它们得到的token不一致它们对应的 `Token-Session` 就不一致,这就为我们不同端的独立数据读写提供了支持:
@@ -91,7 +91,7 @@ session.updateTimeout(1000); // 参数说明和全局有效期保持一致
三种Session创建时机
- `User-Session`: 指的是框架为每个 账号id 分配的 Session
- `Account-Session`: 指的是框架为每个 账号id 分配的 Session
- `Token-Session`: 指的是框架为每个 token 分配的 Session
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId来分配的 Session
@@ -101,7 +101,7 @@ session.updateTimeout(1000); // 参数说明和全局有效期保持一致
![session-model](https://oss.dev33.cn/sa-token/doc/session-model3.png 's-w')
简而言之:
- `User-Session` 以UserId为主只要token指向的UserId一致那么对应的Session对象就一致
- `Account-Session` 以账号 id 为主,只要 token 指向的账号 id 一致那么对应的Session对象就一致
- `Token-Session` 以token为主只要token不同那么对应的Session对象就不同
- `Custom-Session` 以特定的key为主不同key对应不同的Session对象同样的key指向同一个Session对象

View File

@@ -13,7 +13,7 @@ token信息Model: 用来描述一个token的常用参数
"loginId": "10001", // 此token对应的LoginId未登录时为null
"loginType": "login", // 账号类型标识
"tokenTimeout": 2591977, // token剩余有效期 (单位: 秒)
"sessionTimeout": 2591977, // User-Session剩余有效时间 (单位: 秒)
"sessionTimeout": 2591977, // Account-Session剩余有效时间 (单位: 秒)
"tokenSessionTimeout": -2, // Token-Session剩余有效时间 (单位: 秒) (-2表示系统中不存在这个缓存)
"tokenActivityTimeout": -1, // token剩余无操作有效时间 (单位: 秒)
"loginDevice": "default-device" // 登录设备类型

View File

@@ -562,8 +562,8 @@ SaRouter.match("/**").notMatch("/login", "/reg").check(r -> StpUtil.checkLogin()
### QStpUtil.getSession()必须登录后才能调用吗?如果我想在用户未登录之前存储一些数据应该怎么办?
`StpUtil.getSession()`获取的是`User-Session`必须登录后才能使用如果需要在未登录状态下也使用Session功能请使用`Token-Session` <br>
步骤:先在配置文件里将`tokenSessionCheckLogin`配置为`false`,然后通过`StpUtil.getTokenSession()`获取Session
`StpUtil.getSession()`获取的是`Account-Session`必须登录后才能使用如果需要在未登录状态下也使用Session功能请使用`Token-Session` <br>
步骤:先在配置文件里将`tokenSessionCheckLogin`配置为`false`,然后通过`StpUtil.getTokenSession()`获取Session 。或者直接调用 `StpUtil.getAnonTokenSession()` 获取匿名 Token-Session。
### Q我只使用header来传输token还需要打开Cookie模式吗

View File

@@ -24,7 +24,7 @@ Sa-Token 无意发明任何晦涩概念提升逼格,但在处理 issue 、Q群
#### 三种Session
- User-Session框架为每个账号分配的 Session 对象也称账号Session。
- Account-Session框架为每个账号分配的 Session 对象也称账号Session。
- Token-Session框架为每个 Token 分配的 Session 对象也称令牌Session。
- Custom-Session以一个特定的值作为SessionId来分配的 Session 对象也称自定义Session。

View File

@@ -3,7 +3,7 @@
以上介绍的 API 都是操作当前账号,对当前账号进行各种鉴权操作,你可能会问,我能不能对别的账号进行一些操作?<br>
比如:查看账号 10001 有无某个权限码、获取 账号 id=10002 的 `User-Session`,等等...
比如:查看账号 10001 有无某个权限码、获取 账号 id=10002 的 `Account-Session`,等等...
Sa-Token 在 API 设计时充分考虑了这一点暴露出多个api进行此类操作

View File

@@ -297,7 +297,7 @@ sa-token.oauth2.is-client=true
配置含义:同一账号最大登录数量。
在配置 `isConcurrent=true`, `isShare=false` 时Sa-Token 将允许同一账号并发登录且每次登录都会产生一个新Token
这些 Token 都会以 `TokenSign` 的形式记录在其 `User-Session` 之上,这就造成一个问题:
这些 Token 都会以 `TokenSign` 的形式记录在其 `Account-Session` 之上,这就造成一个问题:
随着同一账号登录的次数越来越多TokenSign 的列表也会越来越大,极端情况下,列表长度可能达到成百上千以上,严重拖慢数据处理速度,
为此 Sa-Token 对这个 TokenSign 列表的大小设定一个上限值,也就是 `maxLoginCount`,默认值=12。
@@ -310,7 +310,7 @@ sa-token.oauth2.is-client=true
在调用 `StpUtil.login(id)` 登录后,
- 调用 `StpUtil.getSession()` 可以获取这个会话的 `User-Session` 对象。
- 调用 `StpUtil.getSession()` 可以获取这个会话的 `Account-Session` 对象。
- 调用 `StpUtil.getTokenSession()` 可以获取这个会话 `Token-Session` 对象。
关于两种 Session 有何区别,可以参考这篇:[Session模型详解](/fun/session-model),此处暂不赘述。

View File

@@ -16,14 +16,14 @@ SysUser user = (SysUser) StpUtil.getSession().get("user");
在 Sa-Token 中Session 分为三种,分别是:
- `User-Session`: 指的是框架为每个 账号id 分配的 Session
- `Account-Session`: 指的是框架为每个 账号id 分配的 Session
- `Token-Session`: 指的是框架为每个 token 分配的 Session
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId来分配的 Session
> 有关User-Session与Token-Session的详细区别可参考[Session模型详解](/fun/session-model)
> 有关Account-Session与Token-Session的详细区别可参考[Session模型详解](/fun/session-model)
### User-Session
### Account-Session
有关账号Session的API如下
``` java
// 获取当前账号id的Session (必须是登录后才能调用)

View File

@@ -99,7 +99,7 @@ public class ManyLoginTest {
// token1会被标记为已被顶下线
Assertions.assertEquals(dao.get("satoken:login:token:" + token1), "-4");
// User-Session里的 token1 签名会被移除
// Account-Session里的 token1 签名会被移除
List<TokenSign> tokenSignList = StpUtil.getSessionByLoginId(10001).getTokenSignList();
for (TokenSign tokenSign : tokenSignList) {
Assertions.assertNotEquals(tokenSign.getValue(), token1);
@@ -128,7 +128,7 @@ public class ManyLoginTest {
Assertions.assertNull(dao.get("satoken:login:token:" + token2));
Assertions.assertNull(dao.get("satoken:login:token:" + token3));
// User-Session也应该被清除掉
// Account-Session也应该被清除掉
Assertions.assertNull(StpUtil.getSessionByLoginId(10001, false));
Assertions.assertNull(dao.getSession("satoken:login:session:" + 10001));
}
@@ -155,7 +155,7 @@ public class ManyLoginTest {
Assertions.assertEquals(dao.get("satoken:login:token:" + token2), "-5");
Assertions.assertEquals(dao.get("satoken:login:token:" + token3), "-5");
// User-Session也应该被清除掉
// Account-Session也应该被清除掉
Assertions.assertNull(StpUtil.getSessionByLoginId(10001, false));
Assertions.assertNull(dao.getSession("satoken:login:session:" + 10001));
}