mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 10:08:07 +08:00
重构API
This commit is contained in:
@@ -80,7 +80,7 @@ Sa-Token的API调用非常简单,有多简单呢?以登录验证为例,你
|
||||
|
||||
``` java
|
||||
// 在登录时写入当前会话的账号id
|
||||
StpUtil.setLoginId(10001);
|
||||
StpUtil.login(10001);
|
||||
|
||||
// 然后在任意需要校验登录处调用以下API
|
||||
// 如果当前会话未登录,这句代码会抛出 `NotLoginException`异常
|
||||
@@ -112,7 +112,7 @@ StpUtil.logoutByLoginId(10001);
|
||||
|
||||
除了以上的示例,Sa-Token还可以一行代码完成以下功能:
|
||||
``` java
|
||||
StpUtil.setLoginId(10001); // 标记当前会话登录的账号id
|
||||
StpUtil.login(10001); // 标记当前会话登录的账号id
|
||||
StpUtil.getLoginId(); // 获取当前会话登录的账号id
|
||||
StpUtil.isLogin(); // 获取当前会话是否已经登录, 返回true或false
|
||||
StpUtil.logout(); // 当前会话注销登录
|
||||
@@ -122,7 +122,7 @@ StpUtil.hasPermission("user:add"); // 查询当前账号是否含有指
|
||||
StpUtil.getSession(); // 获取当前账号id的Session
|
||||
StpUtil.getSessionByLoginId(10001); // 获取账号id为10001的Session
|
||||
StpUtil.getTokenValueByLoginId(10001); // 获取账号id为10001的token令牌值
|
||||
StpUtil.setLoginId(10001, "PC"); // 指定设备标识登录
|
||||
StpUtil.login(10001, "PC"); // 指定设备标识登录
|
||||
StpUtil.logoutByLoginId(10001, "PC"); // 指定设备标识进行强制注销 (不同端不受影响)
|
||||
StpUtil.switchTo(10044); // 将当前会话身份临时切换为其它账号
|
||||
```
|
||||
|
@@ -11,7 +11,7 @@ token信息Model: 用来描述一个token的常用参数
|
||||
"tokenValue": "e67b99f1-3d7a-4a8d-bb2f-e888a0805633", // token值
|
||||
"isLogin": true, // 此token是否已经登录
|
||||
"loginId": "10001", // 此token对应的LoginId,未登录时为null
|
||||
"loginKey": "login", // LoginKey账号体系标识
|
||||
"loginType": "login", // 账号类型标识
|
||||
"tokenTimeout": 2591977, // token剩余有效期 (单位: 秒)
|
||||
"sessionTimeout": 2591977, // User-Session剩余有效时间 (单位: 秒)
|
||||
"tokenSessionTimeout": -2, // Token-Session剩余有效时间 (单位: 秒)
|
||||
|
@@ -12,7 +12,7 @@ SaManager.getStpInterface(); // 获取权限认证对象
|
||||
SaManager.getSaTokenAction(); // 获取框架行为对象
|
||||
SaManager.getSaTokenContext(); // 获取上下文处理对象
|
||||
SaManager.getSaTokenListener(); // 获取侦听器对象
|
||||
SaManager.getStpLogic("key"); // 获取指定key的StpLogic对象
|
||||
SaManager.getStpLogic("type"); // 获取指定账号类型的StpLogic对象
|
||||
```
|
||||
|
||||
|
||||
|
@@ -33,8 +33,8 @@
|
||||
`SaRouter.match(Arrays.asList("/**"), Arrays.asList("/login", "/reg"), () -> StpUtil.checkLogin());`
|
||||
|
||||
|
||||
### 为什么StpUtil.setLoginId() 不能直接写入一个User对象?
|
||||
`StpUtil.setLoginId()`只是为了给当前会话做个唯一标记,通常写入`UserId`即可,如果要存储User对象,可以使用`StpUtil.getSession()`获取Session对象进行存储
|
||||
### 为什么StpUtil.login() 不能直接写入一个User对象?
|
||||
`StpUtil.login()`只是为了给当前会话做个唯一标记,通常写入`UserId`即可,如果要存储User对象,可以使用`StpUtil.getSession()`获取Session对象进行存储
|
||||
|
||||
|
||||
### 前后台分离模式下和普通模式有何不同?
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# 更新日志
|
||||
|
||||
### 2021-5-10 @v1.19.0
|
||||
- 新增:注解鉴权新增定制loginKey功能 **[重要]**
|
||||
- 新增:注解鉴权新增定制loginType功能 **[重要]**
|
||||
- 重构:重构目录结构,抽离`plugin`模块 **[重要]**
|
||||
- 新增:新增 `sa-token-quick-login` 插件,零代码集成登录功能 **[重要]**
|
||||
- 优化:所有函数式接口增加`@FunctionalInterface`注解,感谢群友`@MrXionGe`提供的建议
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
### 2021-3-12 @v1.14.0
|
||||
- 新增:新增`SaLoginModel`登录参数Model,适配 [记住我] 模式 **[重要]**
|
||||
- 新增:新增 `StpUtil.setLoginId()` 时指定token有效期,可灵活控制用户的一次登录免验证时长
|
||||
- 新增:新增 `StpUtil.login()` 时指定token有效期,可灵活控制用户的一次登录免验证时长
|
||||
- 新增:新增Cookie时间判断,在`timeout`设置为-1时,`Cookie`有效期将为`Integer.MAX_VALUE` **[重要]**
|
||||
- 新增:新增密码加密工具类,可快速MD5、SHA1、SHA256、AES、RSA加密 **[重要]**
|
||||
- 新增:新增 OAuth2.0 模块 **[重要]**
|
||||
@@ -182,7 +182,7 @@
|
||||
### 2020-5-2 @v1.3.0
|
||||
- 新增:新增 `StpUtil.checkLogin()` 方法,更符合语义化的鉴权方法
|
||||
- 新增:注册拦截器时可设置 `StpLogic` ,方便不同模块不同鉴权方式
|
||||
- 新增:抛出异常时增加 `loginKey` 区分,方便多账号体系鉴权处理
|
||||
- 新增:抛出异常时增加 `loginType` 区分,方便多账号体系鉴权处理
|
||||
- 修复:修复启动时的版本字符画版本号打印不对的bug
|
||||
- 修复:修复文档部分不正确之处
|
||||
- 新增:新增文档的友情链接
|
||||
|
@@ -71,7 +71,7 @@ public class SSOController {
|
||||
@RequestMapping("doLogin")
|
||||
public AjaxJson doLogin(@RequestParam(defaultValue = "10001") String id) {
|
||||
System.out.println("---------------- 进行登录 ");
|
||||
StpUtil.setLoginId(id);
|
||||
StpUtil.login(id);
|
||||
return AjaxJson.getSuccess("登录成功: " + id);
|
||||
}
|
||||
|
||||
|
@@ -77,7 +77,7 @@ public class UserController {
|
||||
public String doLogin(String username, String password) {
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
if("zhang".equals(username) && "123456".equals(password)) {
|
||||
StpUtil.setLoginId(10001);
|
||||
StpUtil.login(10001);
|
||||
return "登录成功";
|
||||
}
|
||||
return "登录失败";
|
||||
|
@@ -83,7 +83,7 @@ public class UserController {
|
||||
public String doLogin(String username, String password) {
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
if("zhang".equals(username) && "123456".equals(password)) {
|
||||
StpUtil.setLoginId(10001);
|
||||
StpUtil.login(10001);
|
||||
return "登录成功";
|
||||
}
|
||||
return "登录失败";
|
||||
|
@@ -21,37 +21,37 @@ public class MySaTokenListener implements SaTokenListener {
|
||||
|
||||
/** 每次登录时触发 */
|
||||
@Override
|
||||
public void doLogin(String loginKey, Object loginId, SaLoginModel loginModel) {
|
||||
public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次注销时触发 */
|
||||
@Override
|
||||
public void doLogout(String loginKey, Object loginId, String tokenValue) {
|
||||
public void doLogout(String loginType, Object loginId, String tokenValue) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被踢下线时触发 */
|
||||
@Override
|
||||
public void doLogoutByLoginId(String loginKey, Object loginId, String tokenValue, String device) {
|
||||
public void doLogoutByLoginId(String loginType, Object loginId, String tokenValue, String device) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被顶下线时触发 */
|
||||
@Override
|
||||
public void doReplaced(String loginKey, Object loginId, String tokenValue, String device) {
|
||||
public void doReplaced(String loginType, Object loginId, String tokenValue, String device) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被封禁时触发 */
|
||||
@Override
|
||||
public void doDisable(String loginKey, Object loginId, long disableTime) {
|
||||
public void doDisable(String loginType, Object loginId, long disableTime) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被解封时触发 */
|
||||
@Override
|
||||
public void doUntieDisable(String loginKey, Object loginId) {
|
||||
public void doUntieDisable(String loginType, Object loginId) {
|
||||
// ...
|
||||
}
|
||||
|
||||
|
@@ -38,7 +38,7 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
* 返回一个账号所拥有的权限码集合
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginKey) {
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("101");
|
||||
@@ -54,7 +54,7 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
* 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginKey) {
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("admin");
|
||||
@@ -88,7 +88,7 @@ StpUtil.checkPermissionAnd("user-update", "user-delete");
|
||||
StpUtil.checkPermissionOr("user-update", "user-delete");
|
||||
```
|
||||
|
||||
扩展:`NotPermissionException` 对象可通过 `getLoginKey()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||
扩展:`NotPermissionException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||
|
||||
|
||||
### 角色认证
|
||||
@@ -108,7 +108,7 @@ StpUtil.checkRoleAnd("super-admin", "shop-admin");
|
||||
StpUtil.checkRoleOr("super-admin", "shop-admin");
|
||||
```
|
||||
|
||||
扩展:`NotRoleException` 对象可通过 `getLoginKey()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||
扩展:`NotRoleException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||
|
||||
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
``` java
|
||||
// 标记当前会话登录的账号id
|
||||
// 建议的参数类型:long | int | String, 不可以传入复杂类型,如:User、Admin等等
|
||||
StpUtil.setLoginId(Object loginId);
|
||||
StpUtil.login(Object loginId);
|
||||
|
||||
// 当前会话注销登录
|
||||
StpUtil.logout();
|
||||
@@ -26,7 +26,7 @@ StpUtil.isLogin();
|
||||
StpUtil.checkLogin()
|
||||
```
|
||||
|
||||
扩展:`NotLoginException` 对象可通过 `getLoginKey()` 方法获取具体是哪个 `StpLogic` 抛出的异常 <br>
|
||||
扩展:`NotLoginException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常 <br>
|
||||
扩展:`NotLoginException` 对象可通过 `getType()` 方法获取具体的场景值,详细参考章节:[未登录场景值](/fun/not-login-scene)
|
||||
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
这样做有两个优点:
|
||||
- `StpLogic`类的所有函数都可以被重写,按需扩展
|
||||
- 在构造方法时随意传入一个不同的 `loginKey`,就可以再造一套账号登录体系
|
||||
- 在构造方法时随意传入一个不同的 `loginType`,就可以再造一套账号登录体系
|
||||
|
||||
|
||||
### 操作示例
|
||||
@@ -25,7 +25,7 @@
|
||||
比如说,对于原生`StpUtil`类,我们只做`admin账号`权限验证,而对于`user账号`,我们则:
|
||||
1. 新建一个新的权限验证类,比如: `StpUserUtil.java`
|
||||
2. 将`StpUtil.java`类的全部代码复制粘贴到 `StpUserUtil.java`里
|
||||
3. 更改一下其 `LoginKey`, 比如:
|
||||
3. 更改一下其 `LoginType`, 比如:
|
||||
|
||||
``` java
|
||||
public class StpUserUtil {
|
||||
@@ -33,7 +33,7 @@ public class StpUserUtil {
|
||||
/**
|
||||
* 账号体系标识
|
||||
*/
|
||||
public static final String KEY = "user"; // 将 LoginKey 从`login`改为`user`
|
||||
public static final String KEY = "user"; // 将 LoginType 从`login`改为`user`
|
||||
|
||||
// 其它代码 ...
|
||||
|
||||
@@ -47,21 +47,21 @@ public class StpUserUtil {
|
||||
### 在多账号模式下使用注解鉴权
|
||||
框架默认的注解鉴权 如`@SaCheckLogin` 只针对原生`StpUtil`进行鉴权
|
||||
|
||||
例如,我们在一个方法上加上`@SaCheckLogin`注解,这个注解只会放行通过`StpUtil.setLoginId(id)`进行登录的会话,
|
||||
而对于通过`StpUserUtil.setLoginId(id)`进行登录的都会话,则始终不会通过校验
|
||||
例如,我们在一个方法上加上`@SaCheckLogin`注解,这个注解只会放行通过`StpUtil.login(id)`进行登录的会话,
|
||||
而对于通过`StpUserUtil.login(id)`进行登录的都会话,则始终不会通过校验
|
||||
|
||||
那么如何告诉`@SaCheckLogin`要鉴别的是哪套账号的登录会话呢?很简单,你只需要指定一下注解的key属性即可:
|
||||
那么如何告诉`@SaCheckLogin`要鉴别的是哪套账号的登录会话呢?很简单,你只需要指定一下注解的type属性即可:
|
||||
|
||||
``` java
|
||||
// 通过key属性指定此注解校验的是我们自定义的`StpUserUtil`,而不是原生`StpUtil`
|
||||
@SaCheckLogin(key = StpUserUtil.KEY)
|
||||
// 通过type属性指定此注解校验的是我们自定义的`StpUserUtil`,而不是原生`StpUtil`
|
||||
@SaCheckLogin(type = StpUserUtil.TYPE)
|
||||
@RequestMapping("info")
|
||||
public String info() {
|
||||
return "查询用户信息";
|
||||
}
|
||||
```
|
||||
|
||||
注:`@SaCheckRole("xxx")`、`@SaCheckPermission("xxx")`同理,亦可根据key属性指定其校验的账号体系,此属性默认为`""`,代表使用原生`StpUtil`账号体系
|
||||
注:`@SaCheckRole("xxx")`、`@SaCheckPermission("xxx")`同理,亦可根据type属性指定其校验的账号体系,此属性默认为`""`,代表使用原生`StpUtil`账号体系
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public static StpLogic stpLogic = new StpLogic("user") {
|
||||
};
|
||||
```
|
||||
|
||||
再次调用 `StpUserUtil.setLoginId(10001)` 进行登录授权时,token的名称将不再是 `satoken`,而是我们重写后的 `satoken-user`
|
||||
再次调用 `StpUserUtil.login(10001)` 进行登录授权时,token的名称将不再是 `satoken`,而是我们重写后的 `satoken-user`
|
||||
|
||||
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#### 指定设备标识登录
|
||||
``` java
|
||||
// 指定`账号id`和`设备标识`进行登录
|
||||
StpUtil.setLoginId(10001, "PC");
|
||||
StpUtil.login(10001, "PC");
|
||||
```
|
||||
调用此方法登录后,同设备的会被顶下线(不同设备不受影响),再次访问系统时会抛出 `NotLoginException` 异常,场景值=`-4`
|
||||
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
### 1、后端将 token 返回到前端
|
||||
|
||||
1. 首先调用 `StpUtil.setLoginId(Object loginId)` 进行登录
|
||||
1. 首先调用 `StpUtil.login(Object loginId)` 进行登录
|
||||
2. 调用 `StpUtil.getTokenInfo()` 返回当前会话的token详细参数
|
||||
- 此方法返回一个对象,其有两个关键属性:`tokenName`和`tokenValue`(`token`的名称和`token`的值)
|
||||
- 将此对象传递到前台,让前端人员将这两个值保存到本地
|
||||
|
@@ -14,7 +14,7 @@ sa-token的登录授权,**默认就是`[记住我]`模式**,为了实现`[
|
||||
|
||||
``` java
|
||||
// 设置登录账号id为10001,第二个参数指定是否为[记住我],当此值为false后,关闭浏览器后再次打开需要重新登录
|
||||
StpUtil.setLoginId(10001, false);
|
||||
StpUtil.login(10001, false);
|
||||
```
|
||||
|
||||
那么,sa-token实现`[记住我]`的具体原理是?
|
||||
@@ -26,8 +26,8 @@ Cookie作为浏览器提供的默认会话跟踪机制,其生命周期有两
|
||||
- 永久Cookie:有效期为一个具体的时间,在时间未到期之前,即使用户关闭了浏览器Cookie也不会消失
|
||||
|
||||
利用Cookie的此特性,我们便可以轻松实现 [记住我] 模式:
|
||||
- 勾选[记住我]按钮时:调用`StpUtil.setLoginId(10001, true)`,在浏览器写入一个`永久Cookie`储存token,此时用户即使重启浏览器token依然有效
|
||||
- 不勾选[记住我]按钮时:调用`StpUtil.setLoginId(10001, false)`,在浏览器写入一个`临时Cookie`储存token,此时用户在重启浏览器后token便会消失,导致会话失效
|
||||
- 勾选[记住我]按钮时:调用`StpUtil.login(10001, true)`,在浏览器写入一个`永久Cookie`储存token,此时用户即使重启浏览器token依然有效
|
||||
- 不勾选[记住我]按钮时:调用`StpUtil.login(10001, false)`,在浏览器写入一个`临时Cookie`储存token,此时用户在重启浏览器后token便会消失,导致会话失效
|
||||
|
||||
|
||||
### 前后台分离模式下如何实现[记住我]?
|
||||
@@ -64,11 +64,11 @@ Remember me, it's too easy!
|
||||
``` java
|
||||
// 示例1:
|
||||
// 指定token有效期(单位: 秒),如下所示token七天有效
|
||||
StpUtil.setLoginId(10001, new SaLoginModel().setTimeout(60 * 60 * 24 * 7));
|
||||
StpUtil.login(10001, new SaLoginModel().setTimeout(60 * 60 * 24 * 7));
|
||||
|
||||
// ----------------------- 示例2:所有参数
|
||||
// `SaLoginModel`为登录参数Model,其有诸多参数决定登录时的各种逻辑,例如:
|
||||
StpUtil.setLoginId(10001, new SaLoginModel()
|
||||
StpUtil.login(10001, new SaLoginModel()
|
||||
.setDevice("PC") // 此次登录的客户端设备标识, 用于[同端互斥登录]时指定此次登录的设备名称
|
||||
.setIsLastingCookie(true) // 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在)
|
||||
.setTimeout(60 * 60 * 24 * 7) // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值)
|
||||
|
@@ -55,13 +55,13 @@ import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
||||
public class MySaTokenAction extends SaTokenActionDefaultImpl {
|
||||
// 重写token生成策略
|
||||
@Override
|
||||
public String createToken(Object loginId, String loginKey) {
|
||||
public String createToken(Object loginId, String loginType) {
|
||||
return SaTokenInsideUtil.getRandomString(60); // 随机60位字符串
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2、再次调用 `StpUtil.setLoginId(10001)`方法进行登录,观察其生成的token样式:
|
||||
2、再次调用 `StpUtil.login(10001)`方法进行登录,观察其生成的token样式:
|
||||
``` html
|
||||
gfuPSwZsnUhwgz08GTCH4wOgasWtc3odP4HLwXJ7NDGOximTvT4OlW19zeLH
|
||||
```
|
||||
@@ -96,13 +96,13 @@ import cn.hutool.core.util.IdUtil;
|
||||
public class MySaTokenAction extends SaTokenActionDefaultImpl {
|
||||
// 重写token生成策略
|
||||
@Override
|
||||
public String createToken(Object loginId, String loginKey) {
|
||||
public String createToken(Object loginId, String loginType) {
|
||||
return IdUtil.getSnowflake(1, 1).nextIdStr(); // 以雪花算法生成token
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3、再次调用 `StpUtil.setLoginId(10001)`方法进行登录,观察其生成的token样式:
|
||||
3、再次调用 `StpUtil.login(10001)`方法进行登录,观察其生成的token样式:
|
||||
``` html
|
||||
1339604338175250432
|
||||
```
|
Reference in New Issue
Block a user