增加代码示例

This commit is contained in:
click33
2022-10-17 00:25:28 +08:00
parent 7142f4db36
commit 55c981ac2d
22 changed files with 470 additions and 75 deletions

View File

@@ -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>

View File

@@ -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("二级认证失败");
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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 对象,存取值时不会互相影响
// 注意点3SaSession 和 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();
}
}

View File

@@ -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) {

View File

@@ -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 + "]";
}
}

View File

@@ -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("/**");
}
/**