mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
增加代码示例
This commit is contained in:
parent
7142f4db36
commit
55c981ac2d
@ -39,13 +39,6 @@
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 整合 Redis (使用jdk默认序列化方式) -->
|
||||
<!-- <dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency> -->
|
||||
|
||||
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
|
@ -0,0 +1,63 @@
|
||||
package com.pj.cases.up;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token 二级认证示例
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/safe/")
|
||||
public class SafeAuthController {
|
||||
|
||||
/*
|
||||
* 前提:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述
|
||||
*
|
||||
* 测试步骤:
|
||||
1、前端调用 deleteProject 接口,尝试删除仓库。 ---- http://localhost:8081/safe/deleteProject
|
||||
2、后端校验会话尚未完成二级认证,返回: 仓库删除失败,请完成二级认证后再次访问接口。
|
||||
3、前端将信息提示给用户,用户输入密码,调用 openSafe 接口。 ---- http://localhost:8081/safe/openSafe
|
||||
4、后端比对用户输入的密码,完成二级认证,有效期为:120秒。
|
||||
5、前端在 120 秒内再次调用 deleteProject 接口,尝试删除仓库。 ---- http://localhost:8081/safe/deleteProject
|
||||
6、后端校验会话已完成二级认证,返回:仓库删除成功。
|
||||
*/
|
||||
|
||||
// 删除仓库 ---- http://localhost:8081/safe/deleteProject
|
||||
@RequestMapping("deleteProject")
|
||||
public SaResult deleteProject(String projectId) {
|
||||
// 第1步,先检查当前会话是否已完成二级认证
|
||||
// 这个地方既可以通过 StpUtil.isSafe() 手动判断,
|
||||
// 也可以通过 StpUtil.checkSafe() 或者 @SaCheckSafe 来校验(校验不通过时将抛出 NotSafeException 异常)
|
||||
if(!StpUtil.isSafe()) {
|
||||
return SaResult.error("仓库删除失败,请完成二级认证后再次访问接口");
|
||||
}
|
||||
|
||||
// 第2步,如果已完成二级认证,则开始执行业务逻辑
|
||||
// ...
|
||||
|
||||
// 第3步,返回结果
|
||||
return SaResult.ok("仓库删除成功");
|
||||
}
|
||||
|
||||
// 提供密码进行二级认证 ---- http://localhost:8081/safe/openSafe
|
||||
@RequestMapping("openSafe")
|
||||
public SaResult openSafe(String password) {
|
||||
// 比对密码(此处只是举例,真实项目时可拿其它参数进行校验)
|
||||
if("123456".equals(password)) {
|
||||
|
||||
// 比对成功,为当前会话打开二级认证,有效期为120秒
|
||||
StpUtil.openSafe(120);
|
||||
return SaResult.ok("二级认证成功");
|
||||
}
|
||||
|
||||
// 如果密码校验失败,则二级认证也会失败
|
||||
return SaResult.error("二级认证失败");
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.pj.cases;
|
||||
package com.pj.cases.use;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -21,7 +21,7 @@ import cn.dev33.satoken.util.SaResult;
|
||||
public class AtCheckController {
|
||||
|
||||
/*
|
||||
* 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*
|
||||
* 前提2:项目在配置类中注册拦截器 SaInterceptor ,代码在 com.pj.satoken.SaTokenConfigure
|
@ -1,4 +1,4 @@
|
||||
package com.pj.cases;
|
||||
package com.pj.cases.use;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -19,7 +19,7 @@ import cn.dev33.satoken.util.SaResult;
|
||||
public class JurAuthController {
|
||||
|
||||
/*
|
||||
* 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* 前提1:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*
|
||||
* 前提2:项目实现 StpInterface 接口,代码在 com.pj.satoken.StpInterfaceImpl
|
@ -1,4 +1,4 @@
|
||||
package com.pj.cases;
|
||||
package com.pj.cases.use;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -17,7 +17,7 @@ import cn.dev33.satoken.util.SaResult;
|
||||
public class KickoutController {
|
||||
|
||||
/*
|
||||
* 前提:首先调用登录接口进行登录,代码在 com.pj.cases.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* 前提:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述
|
||||
* ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.pj.cases;
|
||||
package com.pj.cases.use;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
@ -0,0 +1,27 @@
|
||||
package com.pj.cases.use;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* 为路由拦截鉴权准备的路示例
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-15
|
||||
*/
|
||||
@RestController
|
||||
public class RouterCheckController {
|
||||
|
||||
// 路由拦截鉴权测试 ---- http://localhost:8081/xxx
|
||||
@RequestMapping({
|
||||
"/user/doLogin", "/user/doLogin2",
|
||||
"/user/info", "/admin/info", "/goods/info", "/orders/info", "/notice/info", "/comment/info",
|
||||
"/router/print", "/router/print2"
|
||||
})
|
||||
public SaResult checkLogin() {
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.pj.cases.use;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.pj.model.SysUser;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.session.SaSessionCustomUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token Session会话示例
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/session/")
|
||||
public class SaSessionController {
|
||||
|
||||
/*
|
||||
* 前提:首先调用登录接口进行登录,代码在 com.pj.cases.use.LoginAuthController 中有详细解释,此处不再赘述
|
||||
*/
|
||||
|
||||
// 简单存取值 ---- http://localhost:8081/session/getValue
|
||||
@RequestMapping("getValue")
|
||||
public SaResult getValue() {
|
||||
// 获取当前登录账号的专属 SaSession 对象
|
||||
// 注意点1:只有登录后才可以调用这个方法
|
||||
// 注意点2:每个账号获取到的都是不同的 SaSession 对象,存取值时不会互相影响
|
||||
// 注意点3:SaSession 和 HttpSession 是两个完全不同的对象,不可混淆使用
|
||||
SaSession session = StpUtil.getSession();
|
||||
|
||||
// 存值
|
||||
session.set("name", "zhangsan");
|
||||
session.set("age", 18);
|
||||
|
||||
// 取值
|
||||
Object name = session.get("name");
|
||||
String name2 = session.getString("name"); // 取值,并转化为 String 数据类型
|
||||
int age = session.getInt("age"); // 转 int 类型
|
||||
long age2 = session.getLong("age"); // 转 long 类型
|
||||
float age3 = session.getFloat("age"); // 转 float 类型
|
||||
double age4 = session.getDouble("age"); // 转 double 类型
|
||||
int age5 = session.get("age5", 22); // 取不到时就返回默认值
|
||||
int age6 = session.get("age5", () -> { // 取不到时就执行 lambda 获取值
|
||||
return 26;
|
||||
});
|
||||
|
||||
/*
|
||||
* 存取值范围是一次会话有效的,也就是说,在一次登录有效期内,你可以在一个请求里存值,然后在另一个请求里取值
|
||||
*/
|
||||
|
||||
List<Object> list = Arrays.asList(name, name2, age, age2, age3, age4, age5, age6);
|
||||
System.out.println(list);
|
||||
|
||||
return SaResult.data(list);
|
||||
}
|
||||
|
||||
// 复杂存取值 ---- http://localhost:8081/session/getModel
|
||||
@RequestMapping("getModel")
|
||||
public SaResult setValue() {
|
||||
// 实例化
|
||||
SysUser user = new SysUser();
|
||||
user.setId(10001);
|
||||
user.setName("张三");
|
||||
user.setAge(19);
|
||||
|
||||
// 写入这个对象到 SaSession 中
|
||||
StpUtil.getSession().set("user", user);
|
||||
|
||||
// 然后我们就可以在任意代码处获取这个 user 了
|
||||
SysUser user2 = StpUtil.getSession().getModel("user", SysUser.class);
|
||||
|
||||
// 返回
|
||||
return SaResult.data(user2);
|
||||
}
|
||||
|
||||
// 自定义Session ---- http://localhost:8081/session/customSession
|
||||
@RequestMapping("customSession")
|
||||
public SaResult customSession() {
|
||||
|
||||
// 自定义 Session 就是指使用一个特定的 key,来获取 Session 对象
|
||||
SaSession roleSession = SaSessionCustomUtil.getSessionById("role-1001");
|
||||
|
||||
// 一样可以自由的存值写值
|
||||
roleSession.set("nnn", "lalala");
|
||||
System.out.println(roleSession.get("nnn"));
|
||||
|
||||
// 返回
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.exception.NotPermissionException;
|
||||
import cn.dev33.satoken.exception.NotRoleException;
|
||||
import cn.dev33.satoken.exception.NotSafeException;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
@ -39,6 +40,13 @@ public class GlobalException {
|
||||
return SaResult.error("缺少角色:" + e.getRole());
|
||||
}
|
||||
|
||||
// 拦截:二级认证校验失败异常
|
||||
@ExceptionHandler(NotSafeException.class)
|
||||
public SaResult handlerException(NotSafeException e) {
|
||||
e.printStackTrace();
|
||||
return SaResult.error("二级认证校验失败");
|
||||
}
|
||||
|
||||
// 拦截:其它所有异常
|
||||
@ExceptionHandler(Exception.class)
|
||||
public SaResult handlerException(Exception e) {
|
||||
|
@ -0,0 +1,84 @@
|
||||
package com.pj.model;
|
||||
|
||||
/**
|
||||
* User 实体类
|
||||
*
|
||||
* @author kong
|
||||
* @since 2022-10-15
|
||||
*/
|
||||
public class SysUser {
|
||||
|
||||
public SysUser() {
|
||||
}
|
||||
|
||||
public SysUser(long id, String name, int age) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private long id;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 用户年龄
|
||||
*/
|
||||
private int age;
|
||||
|
||||
/**
|
||||
* @return id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id 要设置的 id
|
||||
*/
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 要设置的 name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return age
|
||||
*/
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param age 要设置的 age
|
||||
*/
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SysUser [id=" + id + ", name=" + name + ", age=" + age + "]";
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
@ -28,7 +30,36 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册 Sa-Token 拦截器打开注解鉴权功能
|
||||
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
|
||||
registry.addInterceptor(new SaInterceptor(handle -> {
|
||||
|
||||
// 指定一条 match 规则
|
||||
SaRouter
|
||||
.match("/user/**") // 拦截的 path 列表,可以写多个
|
||||
.notMatch("/user/doLogin", "/user/doLogin2") // 排除掉的 path 列表,可以写多个
|
||||
.check(r -> StpUtil.checkLogin()); // 要执行的校验动作,可以写完整的 lambda 表达式
|
||||
|
||||
// 权限校验 -- 不同模块认证不同权限
|
||||
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||
SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
|
||||
SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
|
||||
SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
|
||||
SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
|
||||
|
||||
// 甚至你可以随意的写一个打印语句
|
||||
SaRouter.match("/router/print", r -> System.out.println("----啦啦啦----"));
|
||||
|
||||
// 写一个完整的 lambda
|
||||
SaRouter.match("/router/print2", r -> {
|
||||
System.out.println("----啦啦啦2----");
|
||||
// ... 其它代码
|
||||
});
|
||||
|
||||
/*
|
||||
* 相关路由都定义在 com.pj.cases.use.RouterCheckController 中
|
||||
*/
|
||||
|
||||
})).addPathPatterns("/**");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,31 +26,57 @@
|
||||
### 3、设置配置文件
|
||||
你可以**零配置启动项目** ,但同时你也可以在 `application.yml` 中增加如下配置,定制性使用框架:
|
||||
|
||||
<!------------------------------ tabs:start ------------------------------>
|
||||
|
||||
<!------------- tab:application.yml 风格 ------------->
|
||||
``` java
|
||||
server:
|
||||
# 端口
|
||||
port: 8081
|
||||
|
||||
# Sa-Token配置
|
||||
############## Sa-Token 配置 ##############
|
||||
sa-token:
|
||||
# token 名称 (同时也是cookie名称)
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: satoken
|
||||
# token 有效期,单位s 默认30天, -1代表永不过期
|
||||
# token有效期,单位s 默认30天, -1代表永不过期
|
||||
timeout: 2592000
|
||||
# token 临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
activity-timeout: -1
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
is-share: false
|
||||
is-share: true
|
||||
# token风格
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
```
|
||||
|
||||
如果你习惯于 `application.properties` 类型配置文件,那也很好办: <br>
|
||||
百度: [springboot properties与yml 配置文件的区别](https://www.baidu.com/s?ie=UTF-8&wd=springboot%20properties%E4%B8%8Eyml%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB)
|
||||
<!------------- tab:application.properties 风格 ------------->
|
||||
``` java
|
||||
server:
|
||||
# 端口
|
||||
port: 8081
|
||||
|
||||
############## Sa-Token 配置 ##############
|
||||
|
||||
# token名称 (同时也是cookie名称)
|
||||
sa-token.token-name=satoken
|
||||
# token有效期,单位s 默认30天, -1代表永不过期
|
||||
sa-token.timeout=2592000
|
||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
sa-token.activity-timeout=-1
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
sa-token.is-concurrent=true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
sa-token.is-share=true
|
||||
# token风格
|
||||
sa-token.token-style=uuid
|
||||
# 是否输出操作日志
|
||||
sa-token.is-log=false
|
||||
```
|
||||
|
||||
<!---------------------------- tabs:end ------------------------------>
|
||||
|
||||
|
||||
### 4、创建启动类
|
||||
|
@ -166,7 +166,7 @@ body{font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu
|
||||
/* 调整表格的响应式 */
|
||||
#main table{margin-left: 0px;}
|
||||
@media screen and (min-width: 800px) {
|
||||
#main table tr th{min-width: 150px;}
|
||||
#main table tr th{min-width: 100px;}
|
||||
}
|
||||
|
||||
/* 提示框加上灰色背景 */
|
||||
@ -255,6 +255,8 @@ body {
|
||||
padding: 8px 14px;
|
||||
font-size: 14px;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none !important;
|
||||
font-weight: 400;
|
||||
|
||||
/* 背景 */
|
||||
background-image: url(icon/dati.svg);
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Sa-Token 集成 Redis
|
||||
---
|
||||
|
||||
Sa-token 默认将数据保存在内存中,此模式读写速度最快,且避免了序列化与反序列化带来的性能消耗,但是此模式也有一些缺点,比如:
|
||||
Sa-Token 默认将数据保存在内存中,此模式读写速度最快,且避免了序列化与反序列化带来的性能消耗,但是此模式也有一些缺点,比如:
|
||||
|
||||
1. 重启后数据会丢失。
|
||||
2. 无法在分布式环境中共享数据。
|
||||
|
@ -58,14 +58,14 @@ public String add() {
|
||||
public SaResult deleteProject(String projectId) {
|
||||
// 第1步,先检查当前会话是否已完成二级认证
|
||||
if(!StpUtil.isSafe()) {
|
||||
return SaResult.error("请完成二级认证后再次访问接口");
|
||||
return SaResult.error("仓库删除失败,请完成二级认证后再次访问接口");
|
||||
}
|
||||
|
||||
|
||||
// 第2步,如果已完成二级认证,则开始执行业务逻辑
|
||||
// ...
|
||||
|
||||
|
||||
// 第3步,返回结果
|
||||
return SaResult.ok();
|
||||
return SaResult.ok("仓库删除成功");
|
||||
}
|
||||
|
||||
// 提供密码进行二级认证
|
||||
@ -86,9 +86,16 @@ public SaResult openSafe(String password) {
|
||||
|
||||
调用步骤:
|
||||
1. 前端调用 `deleteProject` 接口,尝试删除仓库。
|
||||
2. 后端校验会话尚未完成二级认证,返回: `请完成二级认证后再次访问接口`。
|
||||
2. 后端校验会话尚未完成二级认证,返回: `仓库删除失败,请完成二级认证后再次访问接口`。
|
||||
3. 前端将信息提示给用户,用户输入密码,调用 `openSafe` 接口。
|
||||
4. 后端比对用户输入的密码,完成二级认证,有效期为:120秒。
|
||||
5. 前端在 120 秒内再次调用 `deleteProject` 接口,尝试删除仓库。
|
||||
6. 后端校验会话已完成二级认证,仓库删除成功。
|
||||
6. 后端校验会话已完成二级认证,返回:`仓库删除成功`。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/up/SafeAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 二级认证 —— [ com.pj.cases.up.SafeAuthController.java ]
|
||||
</a>
|
@ -1,11 +1,7 @@
|
||||
# 注解鉴权
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/AtCheckController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 注解鉴权 —— [ com.pj.cases.AtCheckController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
### 注解鉴权
|
||||
|
||||
有同学表示:尽管使用代码鉴权非常方便,但是我仍希望把鉴权逻辑和业务逻辑分离开来,我可以使用注解鉴权吗?当然可以!<br>
|
||||
|
||||
@ -162,6 +158,11 @@ public class TestController {
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/AtCheckController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 注解鉴权 —— [ com.pj.cases.use.AtCheckController.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/ARJvIbA/" target="_blank">本章小练习:Sa-Token 基础 - 注解鉴权,章节测试</a>
|
||||
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
# 框架配置
|
||||
你可以**零配置启动框架** <br>
|
||||
但同时你也可以通过配置,定制性使用框架,`Sa-Token`支持多种方式配置框架信息
|
||||
|
||||
|
||||
|
||||
你可以**零配置启动框架**,但同时你也可以通过一定的参数配置,定制性使用框架,`Sa-Token`支持多种方式配置框架信息
|
||||
|
||||
---
|
||||
|
||||
### 方式1、在 application.yml 配置
|
||||
|
||||
<!------------------------------ tabs:start ------------------------------>
|
||||
|
||||
<!------------- tab:application.yml 风格 ------------->
|
||||
``` java
|
||||
# Sa-Token 配置
|
||||
############## Sa-Token 配置 ##############
|
||||
############## 在线参考:https://sa-token.dev33.cn/doc.html#/use/config ##############
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: satoken
|
||||
@ -27,19 +29,42 @@ sa-token:
|
||||
is-log: false
|
||||
```
|
||||
|
||||
如果你习惯于 `application.properties` 类型的配置文件,那也很好办: 百度: [springboot properties与yml 配置文件的区别](https://www.baidu.com/s?ie=UTF-8&wd=springboot%20properties%E4%B8%8Eyml%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB)
|
||||
<!------------- tab:application.properties 风格 ------------->
|
||||
``` java
|
||||
############## Sa-Token 配置 ##############
|
||||
############## 在线参考:https://sa-token.dev33.cn/doc.html#/use/config ##############
|
||||
|
||||
# token名称 (同时也是cookie名称)
|
||||
sa-token.token-name=satoken
|
||||
# token有效期,单位s 默认30天, -1代表永不过期
|
||||
sa-token.timeout=2592000
|
||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
sa-token.activity-timeout=-1
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
sa-token.is-concurrent=true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
sa-token.is-share=true
|
||||
# token风格
|
||||
sa-token.token-style=uuid
|
||||
# 是否输出操作日志
|
||||
sa-token.is-log=false
|
||||
```
|
||||
|
||||
<!---------------------------- tabs:end ------------------------------>
|
||||
|
||||
|
||||
|
||||
### 方式2、通过代码配置
|
||||
模式1:
|
||||
|
||||
<!------------------------------ tabs:start ------------------------------>
|
||||
<!------------- tab:模式 1 ------------->
|
||||
``` java
|
||||
/**
|
||||
* Sa-Token代码方式进行配置
|
||||
*/
|
||||
@Configuration
|
||||
public class SaTokenConfigure {
|
||||
|
||||
// 获取配置Bean (以代码的方式配置Sa-Token, 此配置会覆盖yml中的配置)
|
||||
// 获取配置Bean (以代码的方式配置Sa-Token, 此配置会覆盖 application.yml 中的配置)
|
||||
@Bean
|
||||
@Primary
|
||||
public SaTokenConfig getSaTokenConfigPrimary() {
|
||||
@ -53,21 +78,36 @@ public class SaTokenConfigure {
|
||||
config.setIsLog(false); // 是否输出操作日志
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
模式2:
|
||||
<!------------- tab:模式 2 ------------->
|
||||
``` java
|
||||
// 以代码的方式配置Sa-Token-Config
|
||||
@Autowired
|
||||
public void configSaToken(SaTokenConfig config) {
|
||||
// config.setTokenName("satoken333"); // token名称 (同时也是cookie名称)
|
||||
// ...
|
||||
/**
|
||||
* Sa-Token代码方式进行配置
|
||||
*/
|
||||
@Configuration
|
||||
public class SaTokenConfigure {
|
||||
// 以代码的方式配置 SaTokenConfig
|
||||
// 此配置会与 application.yml 中的配置合并 (代码配置优先)
|
||||
@Autowired
|
||||
public void configSaToken(SaTokenConfig config) {
|
||||
SaTokenConfig config = new SaTokenConfig();
|
||||
config.setTokenName("satoken"); // token名称 (同时也是cookie名称)
|
||||
config.setTimeout(30 * 24 * 60 * 60); // token有效期,单位s 默认30天
|
||||
config.setActivityTimeout(-1); // token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
config.setIsConcurrent(true); // 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
config.setIsShare(true); // 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
config.setTokenStyle("uuid"); // token风格
|
||||
config.setIsLog(false); // 是否输出操作日志
|
||||
return config;
|
||||
}
|
||||
}
|
||||
```
|
||||
<!---------------------------- tabs:end ------------------------------>
|
||||
|
||||
PS:两者的区别在于:**`模式1会覆盖yml中的配置,模式2会与yml中的配置合并`**
|
||||
两者的区别在于:
|
||||
- 模式 1 会覆盖 application.yml 中的配置。
|
||||
- 模式 2 会与 application.yml 中的配置合并(代码配置优先)。
|
||||
|
||||
|
||||
---
|
||||
|
@ -1,10 +1,5 @@
|
||||
# 权限认证
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/JurAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 权限认证 —— [ com.pj.cases.JurAuthController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -196,4 +191,9 @@ StpUtil.hasPermission("index.html"); // false
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/JurAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 权限认证 —— [ com.pj.cases.use.JurAuthController.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/ZfIjYr9/" target="_blank">本章小练习:Sa-Token 基础 - 权限认证,章节测试</a>
|
||||
|
@ -1,14 +1,5 @@
|
||||
# 踢人下线
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/KickoutController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 踢人下线 —— [ com.pj.cases.KickoutController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
### 设计思路
|
||||
|
||||
所谓踢人下线,核心操作就是找到指定 `loginId` 对应的 `Token`,并设置其失效。
|
||||
|
||||

|
||||
@ -40,6 +31,11 @@ StpUtil.kickoutByTokenValue("token"); // 将指定 Token 踢下线
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/KickoutController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 踢人下线 —— [ com.pj.cases.use.KickoutController.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/MFNN7bK/" target="_blank">本章小练习:Sa-Token 基础 - 踢人下线,章节测试</a>
|
||||
|
||||
|
||||
|
@ -1,10 +1,5 @@
|
||||
# 登录认证
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/LoginAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 登录认证 —— [ com.pj.cases.LoginAuthController.java ]
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -175,5 +170,10 @@ public class LoginController {
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/LoginAuthController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 登录认证 —— [ com.pj.cases.use.LoginAuthController.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/UZBZJvb2ej/" target="_blank">本章小练习:Sa-Token 基础 - 登录认证,章节测试</a>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
# 路由拦截鉴权
|
||||
|
||||
---
|
||||
|
||||
假设我们有如下需求:
|
||||
@ -41,6 +42,12 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册 Sa-Token 拦截器,定义详细认证规则
|
||||
registry.addInterceptor(new SaInterceptor(handler -> {
|
||||
// 指定一条 match 规则
|
||||
SaRouter
|
||||
.match("/**") // 拦截的 path 列表,可以写多个
|
||||
.notMatch("/user/doLogin") // 排除掉的 path 列表,可以写多个
|
||||
.check(r -> StpUtil.checkLogin()); // 要执行的校验动作,可以写完整的 lambda 表达式
|
||||
|
||||
// 根据路由划分模块,不同模块不同鉴权
|
||||
SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
||||
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||
@ -68,13 +75,13 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
// 注册路由拦截器,自定义认证规则
|
||||
registry.addInterceptor(new SaInterceptor(handler -> {
|
||||
|
||||
// 登录认证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
|
||||
// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
|
||||
SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());
|
||||
|
||||
// 角色认证 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证
|
||||
// 角色校验 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证
|
||||
SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));
|
||||
|
||||
// 权限认证 -- 不同模块认证不同权限
|
||||
// 权限校验 -- 不同模块校验不同权限
|
||||
SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
||||
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||
SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
|
||||
@ -227,6 +234,11 @@ public void addInterceptors(InterceptorRegistry registry) {
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/SaTokenConfigure.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token 路由拦截鉴权 —— [ com.pj.satoken.SaTokenConfigure.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/rY7VFv/" target="_blank">本章小练习:Sa-Token 基础 - 路由拦截鉴权,章节测试</a>
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Session会话
|
||||
|
||||
---
|
||||
|
||||
### Session是什么?
|
||||
@ -169,5 +170,10 @@ StpUtil.getAnonTokenSession();
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/SaSessionController.java"
|
||||
target="_blank">
|
||||
本章代码示例:Sa-Token Session 会话 —— [ com.pj.cases.use.SaSessionController.java ]
|
||||
</a>
|
||||
<a class="dt-btn" href="https://www.wenjuan.ltd/s/MNnUr2V/" target="_blank">本章小练习:Sa-Token 基础 - Session 会话,章节测试</a>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user