mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-18 17:48:03 +08:00
增加代码示例
This commit is contained in:
@@ -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("/**");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user