mirror of
https://gitee.com/dromara/sa-token.git
synced 2024-11-30 02:48:10 +08:00
优化文档
This commit is contained in:
parent
a05b4af075
commit
f344d7fda8
@ -143,7 +143,7 @@ public class SaOAuth2ServerController {
|
|||||||
public class SaOAuth2ServerApplication {
|
public class SaOAuth2ServerApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SaOAuth2ServerApplication.class, args);
|
SpringApplication.run(SaOAuth2ServerApplication.class, args);
|
||||||
System.out.println("\nSa-Token-OAuth Server端启动成功");
|
System.out.println("\nSa-Token-OAuth Server 端启动成功");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<!---------------------------- tabs:start ---------------------------->
|
<!---------------------------- tabs:start ---------------------------->
|
||||||
<!-------- tab:Maven 方式 -------->
|
<!-------- tab:Maven 方式 -------->
|
||||||
|
|
||||||
注:如果你使用的是 `SpringBoot 3.x`,只需要将 `sa-token-spring-boot-starter` 修改为 `sa-token-spring-boot3-starter` 即可。
|
注:如果你使用的是 SpringBoot 3.x,只需要将 `sa-token-spring-boot-starter` 修改为 `sa-token-spring-boot3-starter` 即可。
|
||||||
|
|
||||||
``` xml
|
``` xml
|
||||||
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<!-------- tab:Gradle 方式 -------->
|
<!-------- tab:Gradle 方式 -------->
|
||||||
|
|
||||||
注:如果你使用的是 `SpringBoot 3.x`,只需要将 `sa-token-spring-boot-starter` 修改为 `sa-token-spring-boot3-starter` 即可。
|
注:如果你使用的是 SpringBoot 3.x,只需要将 `sa-token-spring-boot-starter` 修改为 `sa-token-spring-boot3-starter` 即可。
|
||||||
|
|
||||||
``` gradle
|
``` gradle
|
||||||
// Sa-Token 权限认证,在线文档:https://sa-token.cc
|
// Sa-Token 权限认证,在线文档:https://sa-token.cc
|
||||||
@ -105,7 +105,7 @@ sa-token.is-log=true
|
|||||||
public class SaTokenDemoApplication {
|
public class SaTokenDemoApplication {
|
||||||
public static void main(String[] args) throws JsonProcessingException {
|
public static void main(String[] args) throws JsonProcessingException {
|
||||||
SpringApplication.run(SaTokenDemoApplication.class, args);
|
SpringApplication.run(SaTokenDemoApplication.class, args);
|
||||||
System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -149,8 +149,8 @@ public class UserController {
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
### 详细了解
|
### 出发
|
||||||
通过这个示例,你已经对 Sa-Token 有了初步的了解,那么现在开始详细了解一下它都有哪些吧:[登录认证](/use/login-auth)
|
通过这个示例,你已经对 Sa-Token 有了初步的了解。那么,坐稳扶好,让我们开始吧:[登录认证](/use/login-auth)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
本篇介绍在 Solon 应用中如何集成 Sa-Token。
|
本篇介绍在 Solon 应用中如何集成 Sa-Token。
|
||||||
|
|
||||||
整合示例在官方仓库的 /sa-token-demo/sa-token-demo-solon 文件夹下,如遇到难点可结合源码进行学习测试。
|
整合示例在官方仓库的 `/sa-token-demo/sa-token-demo-solon` 文件夹下,如遇到难点可结合源码进行学习测试。
|
||||||
|
|
||||||
> Solon 是一个高效的国产应用开发框架:更快、更小、更简单。
|
> Solon 是一个高效的国产应用开发框架:更快、更小、更简单。
|
||||||
>
|
>
|
||||||
@ -119,7 +119,7 @@ sa-token.is-log=true
|
|||||||
public class SaTokenDemoApp {
|
public class SaTokenDemoApp {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Solon.start(SaTokenDemoApp.class, args);
|
Solon.start(SaTokenDemoApp.class, args);
|
||||||
System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -48,7 +48,7 @@ implementation 'cn.dev33:sa-token-reactor-spring-boot-starter:${sa.top.version}'
|
|||||||
public class SaTokenDemoApplication {
|
public class SaTokenDemoApplication {
|
||||||
public static void main(String[] args) throws JsonProcessingException {
|
public static void main(String[] args) throws JsonProcessingException {
|
||||||
SpringApplication.run(SaTokenDemoApplication.class, args);
|
SpringApplication.run(SaTokenDemoApplication.class, args);
|
||||||
System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -6,10 +6,10 @@ Sa-Token 默认将数据保存在内存中,此模式读写速度最快,且
|
|||||||
1. 重启后数据会丢失。
|
1. 重启后数据会丢失。
|
||||||
2. 无法在分布式环境中共享数据。
|
2. 无法在分布式环境中共享数据。
|
||||||
|
|
||||||
为此,Sa-Token 提供了扩展接口,你可以轻松将会话数据存储在 `Redis`、`Memcached`等专业的缓存中间件中,
|
为此,Sa-Token 提供了扩展接口,你可以轻松将会话数据存储在一些专业的缓存中间件上(比如 Redis),
|
||||||
做到重启数据不丢失,而且保证分布式环境下多节点的会话一致性。
|
做到重启数据不丢失,而且保证分布式环境下多节点的会话一致性。
|
||||||
|
|
||||||
以下是官方提供的 Redis 集成包:
|
以下是框架提供的 Redis 集成包:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
而如果我们深入它的源码,[点此阅览](https://gitee.com/dromara/sa-token/blob/master/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java) <br/>
|
而如果我们深入它的源码,[点此阅览](https://gitee.com/dromara/sa-token/blob/master/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java) <br/>
|
||||||
就会发现,此类并没有任何代码逻辑,唯一做的事就是对成员变量`stpLogic`的各个API包装一下进行转发。
|
就会发现,此类并没有任何代码逻辑,唯一做的事就是对成员变量`stpLogic`的各个API包装一下进行转发。
|
||||||
|
|
||||||
这样做有两个优点:
|
这样做有两个好处:
|
||||||
- StpLogic 类的所有函数都可以被重写,按需扩展。
|
- StpLogic 类的所有函数都可以被重写,按需扩展。
|
||||||
- 在构造方法时随意传入一个不同的 `loginType`,就可以再造一套账号登录体系。
|
- 在构造方法时随意传入一个不同的 `loginType`,就可以再造一套账号登录体系。
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
## 内置风格
|
## 内置风格
|
||||||
|
|
||||||
Sa-Token默认的token生成策略是uuid风格,其模样类似于:`623368f0-ae5e-4475-a53f-93e4225f16ae`。<br>
|
Sa-Token 默认的 token 生成策略是 uuid 风格,其模样类似于:`623368f0-ae5e-4475-a53f-93e4225f16ae`。<br>
|
||||||
如果你对这种风格不太感冒,还可以将token生成设置为其他风格。
|
如果你对这种风格不太感冒,还可以将 token 生成设置为其他风格。
|
||||||
|
|
||||||
怎么设置呢?只需要在yml配置文件里设置 `sa-token.token-style=风格类型` 即可,其有多种取值:
|
怎么设置呢?只需要在yml配置文件里设置 `sa-token.token-style=风格类型` 即可,其有多种取值:
|
||||||
|
|
||||||
|
@ -100,8 +100,8 @@ public SaResult atJurOr() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
mode有两种取值:
|
mode有两种取值:
|
||||||
- `SaMode.AND`, 标注一组权限,会话必须全部具有才可通过校验。
|
- `SaMode.AND`,标注一组权限,会话必须全部具有才可通过校验。
|
||||||
- `SaMode.OR`, 标注一组权限,会话只要具有其一即可通过校验。
|
- `SaMode.OR`,标注一组权限,会话只要具有其一即可通过校验。
|
||||||
|
|
||||||
|
|
||||||
### 4、角色权限双重 “or校验”
|
### 4、角色权限双重 “or校验”
|
||||||
@ -116,7 +116,7 @@ public SaResult userAdd() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
orRole 字段代表权限认证未通过时的次要选择,两者只要其一认证成功即可通过校验,其有三种写法:
|
orRole 字段代表权限校验未通过时的次要选择,两者只要其一校验成功即可进入请求方法,其有三种写法:
|
||||||
- 写法一:`orRole = "admin"`,代表需要拥有角色 admin 。
|
- 写法一:`orRole = "admin"`,代表需要拥有角色 admin 。
|
||||||
- 写法二:`orRole = {"admin", "manager", "staff"}`,代表具有三个角色其一即可。
|
- 写法二:`orRole = {"admin", "manager", "staff"}`,代表具有三个角色其一即可。
|
||||||
- 写法三:`orRole = {"admin, manager, staff"}`,代表必须同时具有三个角色。
|
- 写法三:`orRole = {"admin, manager, staff"}`,代表必须同时具有三个角色。
|
||||||
|
@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 1、设计思路
|
||||||
### 设计思路
|
|
||||||
|
|
||||||
所谓权限认证,核心逻辑就是判断一个账号是否拥有指定权限:<br/>
|
所谓权限认证,核心逻辑就是判断一个账号是否拥有指定权限:<br/>
|
||||||
- 有,就让你通过。
|
- 有,就让你通过。
|
||||||
- 没有?那么禁止访问!
|
- 没有?那么禁止访问!
|
||||||
|
|
||||||
深入到底层数据中,就是每个账号都会拥有一个权限码集合,框架来校验这个集合中是否包含指定的权限码。
|
深入到底层数据中,就是每个账号都会拥有一组权限码集合,框架来校验这个集合中是否包含指定的权限码。
|
||||||
|
|
||||||
例如:当前账号拥有权限码集合 `["user-add", "user-delete", "user-get"]`,这时候我来校验权限 `"user-update"`,则其结果就是:**验证失败,禁止访问**。 <br/>
|
例如:当前账号拥有权限码集合 `["user-add", "user-delete", "user-get"]`,这时候我来校验权限 `"user-update"`,则其结果就是:**验证失败,禁止访问**。 <br/>
|
||||||
|
|
||||||
@ -17,11 +16,12 @@
|
|||||||
<button class="show-img" img-src="https://oss.dev33.cn/sa-token/doc/g/g3--jur-auth.gif">加载动态演示图</button>
|
<button class="show-img" img-src="https://oss.dev33.cn/sa-token/doc/g/g3--jur-auth.gif">加载动态演示图</button>
|
||||||
|
|
||||||
|
|
||||||
所以现在问题的核心就是:
|
所以现在问题的核心就是两个:
|
||||||
1. 如何获取一个账号所拥有的的权限码集合?
|
1. 如何获取一个账号所拥有的权限码集合?
|
||||||
2. 本次操作需要验证的权限码是哪个?
|
2. 本次操作需要验证的权限码是哪个?
|
||||||
|
|
||||||
### 获取当前账号权限码集合
|
|
||||||
|
### 2、获取当前账号权限码集合
|
||||||
因为每个项目的需求不同,其权限设计也千变万化,因此 [ 获取当前账号权限码集合 ] 这一操作不可能内置到框架中,
|
因为每个项目的需求不同,其权限设计也千变万化,因此 [ 获取当前账号权限码集合 ] 这一操作不可能内置到框架中,
|
||||||
所以 Sa-Token 将此操作以接口的方式暴露给你,以方便你根据自己的业务逻辑进行重写。
|
所以 Sa-Token 将此操作以接口的方式暴露给你,以方便你根据自己的业务逻辑进行重写。
|
||||||
|
|
||||||
@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
``` java
|
``` java
|
||||||
/**
|
/**
|
||||||
* 自定义权限验证接口扩展
|
* 自定义权限加载接口实现类
|
||||||
*/
|
*/
|
||||||
@Component // 保证此类被SpringBoot扫描,完成Sa-Token的自定义权限验证扩展
|
@Component // 保证此类被 SpringBoot 扫描,完成 Sa-Token 的自定义权限验证扩展
|
||||||
public class StpInterfaceImpl implements StpInterface {
|
public class StpInterfaceImpl implements StpInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +39,7 @@ public class StpInterfaceImpl implements StpInterface {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
// 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||||
List<String> list = new ArrayList<String>();
|
List<String> list = new ArrayList<String>();
|
||||||
list.add("101");
|
list.add("101");
|
||||||
list.add("user.add");
|
list.add("user.add");
|
||||||
@ -55,7 +55,7 @@ public class StpInterfaceImpl implements StpInterface {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRoleList(Object loginId, String loginType) {
|
public List<String> getRoleList(Object loginId, String loginType) {
|
||||||
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
|
// 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询角色
|
||||||
List<String> list = new ArrayList<String>();
|
List<String> list = new ArrayList<String>();
|
||||||
list.add("admin");
|
list.add("admin");
|
||||||
list.add("super-admin");
|
list.add("super-admin");
|
||||||
@ -71,11 +71,12 @@ public class StpInterfaceImpl implements StpInterface {
|
|||||||
|
|
||||||
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
||||||
|
|
||||||
> 注意: StpInterface 接口在需要鉴权时由框架自动调用,开发者只需要配置好就可以使用下面的鉴权方法或后面的注解鉴权
|
> 有同学会产生疑问:我实现了此接口,但是程序启动时好像并没有执行,是不是我写错了?
|
||||||
|
> 答:不执行是正常现象,程序启动时不会执行这个接口的方法,在每次调用鉴权代码时,才会执行到此。
|
||||||
|
|
||||||
|
|
||||||
### 权限校验
|
### 3、权限校验
|
||||||
然后就可以用以下api来鉴权了
|
然后就可以用以下 api 来鉴权了
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
// 获取:当前账号所拥有的权限集合
|
// 获取:当前账号所拥有的权限集合
|
||||||
@ -97,8 +98,8 @@ StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");
|
|||||||
扩展:`NotPermissionException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
扩展:`NotPermissionException` 对象可通过 `getLoginType()` 方法获取具体是哪个 `StpLogic` 抛出的异常
|
||||||
|
|
||||||
|
|
||||||
### 角色校验
|
### 4、角色校验
|
||||||
在Sa-Token中,角色和权限可以独立验证
|
在 Sa-Token 中,角色和权限可以分开独立验证
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
// 获取:当前账号所拥有的角色集合
|
// 获取:当前账号所拥有的角色集合
|
||||||
@ -121,7 +122,7 @@ StpUtil.checkRoleOr("super-admin", "shop-admin");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 拦截全局异常
|
### 5、拦截全局异常
|
||||||
有同学要问,鉴权失败,抛出异常,然后呢?要把异常显示给用户看吗?**当然不可以!**
|
有同学要问,鉴权失败,抛出异常,然后呢?要把异常显示给用户看吗?**当然不可以!**
|
||||||
|
|
||||||
你可以创建一个全局异常拦截器,统一返回给前端的格式,参考:
|
你可以创建一个全局异常拦截器,统一返回给前端的格式,参考:
|
||||||
@ -141,7 +142,7 @@ public class GlobalExceptionHandler {
|
|||||||
可参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/current/GlobalException.java)
|
可参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/current/GlobalException.java)
|
||||||
|
|
||||||
|
|
||||||
### 权限通配符
|
### 6、权限通配符
|
||||||
Sa-Token允许你根据通配符指定**泛权限**,例如当一个账号拥有`art.*`的权限时,`art.add`、`art.delete`、`art.update`都将匹配通过
|
Sa-Token允许你根据通配符指定**泛权限**,例如当一个账号拥有`art.*`的权限时,`art.add`、`art.delete`、`art.update`都将匹配通过
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
@ -164,7 +165,7 @@ StpUtil.hasPermission("index.html"); // false
|
|||||||
!> 上帝权限:当一个账号拥有 `"*"` 权限时,他可以验证通过任何权限码 (角色认证同理)
|
!> 上帝权限:当一个账号拥有 `"*"` 权限时,他可以验证通过任何权限码 (角色认证同理)
|
||||||
|
|
||||||
|
|
||||||
### 如何把权限精确到按钮级?
|
### 7、如何把权限精确到按钮级?
|
||||||
权限精确到按钮级的意思就是指:**权限范围可以控制到页面上的每一个按钮是否显示**。
|
权限精确到按钮级的意思就是指:**权限范围可以控制到页面上的每一个按钮是否显示**。
|
||||||
|
|
||||||
思路:如此精确的范围控制只依赖后端已经难以完成,此时需要前端进行一定的逻辑判断。
|
思路:如此精确的范围控制只依赖后端已经难以完成,此时需要前端进行一定的逻辑判断。
|
||||||
@ -183,10 +184,11 @@ StpUtil.hasPermission("index.html"); // false
|
|||||||
注意:以上写法只为提供一个参考示例,不同框架有不同写法,大家可根据项目技术栈灵活封装进行调用。
|
注意:以上写法只为提供一个参考示例,不同框架有不同写法,大家可根据项目技术栈灵活封装进行调用。
|
||||||
|
|
||||||
|
|
||||||
### 前端有了鉴权后端还需要鉴权吗?
|
### 8、前端有了鉴权后端还需要鉴权吗?
|
||||||
**需要!**
|
**需要!**
|
||||||
|
|
||||||
前端的鉴权只是一个辅助功能,对于专业人员这些限制都是可以轻松绕过的,为保证服务器安全,无论前端是否进行了权限校验,后端接口都需要对会话请求再次进行权限校验!
|
前端的鉴权只是一个辅助功能,对于专业人员这些限制都是可以轻松绕过的,
|
||||||
|
为保证服务器安全,**无论前端是否进行了权限校验,后端接口都需要对会话请求再次进行权限校验!**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
### 设计思路
|
### 1、设计思路
|
||||||
|
|
||||||
对于一些登录之后才能访问的接口(例如:查询我的账号资料),我们通常的做法是增加一层接口校验:
|
对于一些登录之后才能访问的接口(例如:查询我的账号资料),我们通常的做法是增加一层接口校验:
|
||||||
|
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<button class="show-img" img-src="https://oss.dev33.cn/sa-token/doc/g/g3--login-auth.gif">加载动态演示图</button>
|
<button class="show-img" img-src="https://oss.dev33.cn/sa-token/doc/g/g3--login-auth.gif">加载动态演示图</button>
|
||||||
|
|
||||||
|
|
||||||
### 登录与注销
|
### 2、登录与注销
|
||||||
根据以上思路,我们需要一个会话登录的函数:
|
根据以上思路,我们需要一个会话登录的函数:
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
@ -33,13 +33,14 @@ StpUtil.login(Object id);
|
|||||||
|
|
||||||
只此一句代码,便可以使会话登录成功,实际上,Sa-Token 在背后做了大量的工作,包括但不限于:
|
只此一句代码,便可以使会话登录成功,实际上,Sa-Token 在背后做了大量的工作,包括但不限于:
|
||||||
|
|
||||||
1. 检查此账号是否之前已有登录
|
1. 检查此账号是否之前已有登录;
|
||||||
2. 为账号生成 `Token` 凭证与 `Session` 会话
|
2. 为账号生成 `Token` 凭证与 `Session` 会话;
|
||||||
3. 通知全局侦听器,xx 账号登录成功
|
3. 记录 Token 活跃时间;
|
||||||
4. 将 `Token` 注入到请求上下文
|
4. 通知全局侦听器,xx 账号登录成功;
|
||||||
5. 等等其它工作……
|
5. 将 `Token` 注入到请求上下文;
|
||||||
|
6. 等等其它工作……
|
||||||
|
|
||||||
你暂时不需要完整的了解整个登录过程,你只需要记住关键一点:`Sa-Token 为这个账号创建了一个Token凭证,且通过 Cookie 上下文返回给了前端`。
|
你暂时不需要完整了解整个登录过程,你只需要记住关键一点:`Sa-Token 为这个账号创建了一个Token凭证,且通过 Cookie 上下文返回给了前端`。
|
||||||
|
|
||||||
所以一般情况下,我们的登录接口代码,会大致类似如下:
|
所以一般情况下,我们的登录接口代码,会大致类似如下:
|
||||||
|
|
||||||
@ -57,13 +58,13 @@ public SaResult doLogin(String name, String pwd) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你对以上代码阅读没有压力,你可能会注意到略显奇怪的一点:此处仅仅做了会话登录,但并没有主动向前端返回 Token 信息。
|
如果你对以上代码阅读没有压力,你可能会注意到略显奇怪的一点:此处仅仅做了会话登录,但并没有主动向前端返回 token 信息。
|
||||||
是因为不需要吗?严格来讲是需要的,只不过 `StpUtil.login(id)` 方法利用了 Cookie 自动注入的特性,省略了你手写返回 Token 的代码。
|
是因为不需要吗?严格来讲是需要的,只不过 `StpUtil.login(id)` 方法利用了 Cookie 自动注入的特性,省略了你手写返回 token 的代码。
|
||||||
|
|
||||||
如果你对 Cookie 功能还不太了解,也不用担心,我们会在之后的 [ 前后端分离 ] 章节中详细的阐述 Cookie 功能,现在你只需要了解最基本的两点:
|
如果你对 Cookie 功能还不太了解,也不用担心,我们会在之后的 [ 前后端分离 ] 章节中详细的阐述 Cookie 功能,现在你只需要了解最基本的两点:
|
||||||
|
|
||||||
- Cookie 可以从后端控制往浏览器中写入 Token 值。
|
- Cookie 可以从后端控制往浏览器中写入 token 值。
|
||||||
- Cookie 会在前端每次发起请求时自动提交 Token 值。
|
- Cookie 会在前端每次发起请求时自动提交 token 值。
|
||||||
|
|
||||||
因此,在 Cookie 功能的加持下,我们可以仅靠 `StpUtil.login(id)` 一句代码就完成登录认证。
|
因此,在 Cookie 功能的加持下,我们可以仅靠 `StpUtil.login(id)` 一句代码就完成登录认证。
|
||||||
|
|
||||||
@ -81,10 +82,10 @@ StpUtil.checkLogin();
|
|||||||
```
|
```
|
||||||
|
|
||||||
异常 `NotLoginException` 代表当前会话暂未登录,可能的原因有很多:
|
异常 `NotLoginException` 代表当前会话暂未登录,可能的原因有很多:
|
||||||
前端没有提交 Token、前端提交的 Token 是无效的、前端提交的 Token 已经过期 …… 等等,可参照此篇:[未登录场景值](/fun/not-login-scene),了解如何获取未登录的场景值。
|
前端没有提交 token、前端提交的 token 是无效的、前端提交的 token 已经过期 …… 等等,可参照此篇:[未登录场景值](/fun/not-login-scene),了解如何获取未登录的场景值。
|
||||||
|
|
||||||
|
|
||||||
### 会话查询
|
### 3、会话查询
|
||||||
``` java
|
``` java
|
||||||
// 获取当前会话账号id, 如果未登录,则抛出异常:`NotLoginException`
|
// 获取当前会话账号id, 如果未登录,则抛出异常:`NotLoginException`
|
||||||
StpUtil.getLoginId();
|
StpUtil.getLoginId();
|
||||||
@ -96,7 +97,7 @@ StpUtil.getLoginIdAsLong(); // 获取当前会话账号id, 并转化为`lon
|
|||||||
|
|
||||||
// ---------- 指定未登录情形下返回的默认值 ----------
|
// ---------- 指定未登录情形下返回的默认值 ----------
|
||||||
|
|
||||||
// 获取当前会话账号id, 如果未登录,则返回null
|
// 获取当前会话账号id, 如果未登录,则返回 null
|
||||||
StpUtil.getLoginIdDefaultNull();
|
StpUtil.getLoginIdDefaultNull();
|
||||||
|
|
||||||
// 获取当前会话账号id, 如果未登录,则返回默认值 (`defaultValue`可以为任意类型)
|
// 获取当前会话账号id, 如果未登录,则返回默认值 (`defaultValue`可以为任意类型)
|
||||||
@ -104,29 +105,29 @@ StpUtil.getLoginId(T defaultValue);
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Token 查询
|
### 4、token 查询
|
||||||
``` java
|
``` java
|
||||||
// 获取当前会话的token值
|
// 获取当前会话的 token 值
|
||||||
StpUtil.getTokenValue();
|
StpUtil.getTokenValue();
|
||||||
|
|
||||||
// 获取当前`StpLogic`的token名称
|
// 获取当前`StpLogic`的 token 名称
|
||||||
StpUtil.getTokenName();
|
StpUtil.getTokenName();
|
||||||
|
|
||||||
// 获取指定token对应的账号id,如果未登录,则返回 null
|
// 获取指定 token 对应的账号id,如果未登录,则返回 null
|
||||||
StpUtil.getLoginIdByToken(String tokenValue);
|
StpUtil.getLoginIdByToken(String tokenValue);
|
||||||
|
|
||||||
// 获取当前会话剩余有效期(单位:s,返回-1代表永久有效)
|
// 获取当前会话剩余有效期(单位:s,返回-1代表永久有效)
|
||||||
StpUtil.getTokenTimeout();
|
StpUtil.getTokenTimeout();
|
||||||
|
|
||||||
// 获取当前会话的token信息参数
|
// 获取当前会话的 token 信息参数
|
||||||
StpUtil.getTokenInfo();
|
StpUtil.getTokenInfo();
|
||||||
```
|
```
|
||||||
|
|
||||||
有关`TokenInfo`参数详解,请参考:[TokenInfo参数详解](/fun/token-info)
|
有关`TokenInfo`参数详解,请参考:[TokenInfo参数详解](/fun/token-info)
|
||||||
|
|
||||||
|
|
||||||
### 来个小测试,加深一下理解
|
### 5、来个小测试,加深一下理解
|
||||||
新建 `LoginController`,复制以下代码
|
新建 `LoginController`,复制或手动敲出以下代码
|
||||||
``` java
|
``` java
|
||||||
/**
|
/**
|
||||||
* 登录测试
|
* 登录测试
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
我们怎么实现呢?给每个接口加上鉴权注解?手写全局拦截器?似乎都不是非常方便。
|
我们怎么实现呢?给每个接口加上鉴权注解?手写全局拦截器?似乎都不是非常方便。
|
||||||
|
|
||||||
在这个需求中我们真正需要的是一种基于路由拦截的鉴权模式, 那么在Sa-Token怎么实现路由拦截鉴权呢?
|
在这个需求中我们真正需要的是一种基于路由拦截的鉴权模式,那么在Sa-Token怎么实现路由拦截鉴权呢?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1、注册 Sa-Token 路由拦截器
|
### 1、注册 Sa-Token 路由拦截器
|
||||||
以`SpringBoot2.0`为例, 新建配置类`SaTokenConfigure.java`
|
以`SpringBoot2.0`为例,新建配置类`SaTokenConfigure.java`
|
||||||
``` java
|
``` java
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SaTokenConfigure implements WebMvcConfigurer {
|
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Session是什么?
|
### 1、Session是什么?
|
||||||
|
|
||||||
Session是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能,例如:
|
Session 是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能,例如:
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
// 在登录时缓存user对象
|
// 在登录时缓存 user 对象
|
||||||
StpUtil.getSession().set("user", user);
|
StpUtil.getSession().set("user", user);
|
||||||
|
|
||||||
// 然后我们就可以在任意处使用这个user对象
|
// 然后我们就可以在任意处使用这个 user 对象
|
||||||
SysUser user = (SysUser) StpUtil.getSession().get("user");
|
SysUser user = (SysUser) StpUtil.getSession().get("user");
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -20,31 +20,31 @@ SysUser user = (SysUser) StpUtil.getSession().get("user");
|
|||||||
- `Token-Session`: 指的是框架为每个 token 分配的 Session
|
- `Token-Session`: 指的是框架为每个 token 分配的 Session
|
||||||
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId,来分配的 Session
|
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId,来分配的 Session
|
||||||
|
|
||||||
> 有关Account-Session与Token-Session的详细区别,可参考:[Session模型详解](/fun/session-model)
|
> 有关 Account-Session 与 Token-Session 的详细区别,可参考:[Session模型详解](/fun/session-model)
|
||||||
|
|
||||||
|
|
||||||
### Account-Session
|
### Account-Session
|
||||||
有关账号Session的API如下:
|
有关 账号-Session 的 API 如下:
|
||||||
``` java
|
``` java
|
||||||
// 获取当前账号id的Session (必须是登录后才能调用)
|
// 获取当前账号 id 的 Account-Session (必须是登录后才能调用)
|
||||||
StpUtil.getSession();
|
StpUtil.getSession();
|
||||||
|
|
||||||
// 获取当前账号id的Session, 并决定在Session尚未创建时,是否新建并返回
|
// 获取当前账号 id 的 Account-Session, 并决定在 Session 尚未创建时,是否新建并返回
|
||||||
StpUtil.getSession(true);
|
StpUtil.getSession(true);
|
||||||
|
|
||||||
// 获取账号id为10001的Session
|
// 获取账号 id 为 10001 的 Account-Session
|
||||||
StpUtil.getSessionByLoginId(10001);
|
StpUtil.getSessionByLoginId(10001);
|
||||||
|
|
||||||
// 获取账号id为10001的Session, 并决定在Session尚未创建时,是否新建并返回
|
// 获取账号 id 为 10001 的 Account-Session, 并决定在 Session 尚未创建时,是否新建并返回
|
||||||
StpUtil.getSessionByLoginId(10001, true);
|
StpUtil.getSessionByLoginId(10001, true);
|
||||||
|
|
||||||
// 获取SessionId为xxxx-xxxx的Session, 在Session尚未创建时, 返回null
|
// 获取 SessionId 为 xxxx-xxxx 的 Account-Session, 在 Session 尚未创建时, 返回 null
|
||||||
StpUtil.getSessionBySessionId("xxxx-xxxx");
|
StpUtil.getSessionBySessionId("xxxx-xxxx");
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Token-Session
|
### Token-Session
|
||||||
有关令牌Session的API如下:
|
有关 令牌-Session 的 API 如下:
|
||||||
``` java
|
``` java
|
||||||
// 获取当前 Token 的 Token-Session 对象
|
// 获取当前 Token 的 Token-Session 对象
|
||||||
StpUtil.getTokenSession();
|
StpUtil.getTokenSession();
|
||||||
@ -54,9 +54,9 @@ StpUtil.getTokenSessionByToken(token);
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### 自定义Session
|
### Custom-Session
|
||||||
自定义Session指的是以一个`特定的值`作为SessionId来分配的`Session`, 借助自定义Session,你可以为系统中的任意元素分配相应的session<br>
|
自定义 Session 指的是以一个`特定的值`作为 SessionId 来分配的`Session`, 借助自定义Session,你可以为系统中的任意元素分配相应的session<br>
|
||||||
例如以商品id作为key为每个商品分配一个Session,以便于缓存和商品相关的数据,其相关API如下:
|
例如以商品 id 作为 key 为每个商品分配一个Session,以便于缓存和商品相关的数据,其相关API如下:
|
||||||
``` java
|
``` java
|
||||||
// 查询指定key的Session是否存在
|
// 查询指定key的Session是否存在
|
||||||
SaSessionCustomUtil.isExists("goods-10001");
|
SaSessionCustomUtil.isExists("goods-10001");
|
||||||
@ -74,6 +74,8 @@ SaSessionCustomUtil.deleteSessionById("goods-10001");
|
|||||||
|
|
||||||
### 在 Session 上存取值
|
### 在 Session 上存取值
|
||||||
|
|
||||||
|
以上三种 Session 均为框架设计概念上的区分,实际上在获取它们时,返回的都是 SaSession 对象,你可以使用以下 API 在 SaSession 对象上存取值:
|
||||||
|
|
||||||
``` java
|
``` java
|
||||||
// 写值
|
// 写值
|
||||||
session.set("name", "zhang");
|
session.set("name", "zhang");
|
||||||
@ -101,7 +103,7 @@ session.getFloat("result"); // 取值 (转float类型)
|
|||||||
session.getModel("key", Student.class); // 取值 (指定转换类型)
|
session.getModel("key", Student.class); // 取值 (指定转换类型)
|
||||||
session.getModel("key", Student.class, <defaultValue>); // 取值 (指定转换类型, 并指定值为Null时返回的默认值)
|
session.getModel("key", Student.class, <defaultValue>); // 取值 (指定转换类型, 并指定值为Null时返回的默认值)
|
||||||
|
|
||||||
// 是否含有某个key (返回true或false)
|
// 是否含有某个key (返回 true 或 false)
|
||||||
session.has("key");
|
session.has("key");
|
||||||
|
|
||||||
// 删值
|
// 删值
|
||||||
@ -135,8 +137,8 @@ session.logout();
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Session环境隔离说明
|
### 避免与 HttpSession 混淆使用
|
||||||
有同学经常会把 `SaSession` 与 `HttpSession` 进行混淆,例如:
|
经常有同学会把 `SaSession` 与 `HttpSession` 进行混淆,例如:
|
||||||
``` java
|
``` java
|
||||||
@PostMapping("/resetPoints")
|
@PostMapping("/resetPoints")
|
||||||
public void reset(HttpSession session) {
|
public void reset(HttpSession session) {
|
||||||
|
Loading…
Reference in New Issue
Block a user