mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
feat:集成loveqq-framework示例
This commit is contained in:
parent
be5ee2fc2b
commit
bd22a94a10
@ -57,8 +57,9 @@
|
|||||||
<module>sa-token-demo-webflux-springboot3</module>
|
<module>sa-token-demo-webflux-springboot3</module>
|
||||||
<module>sa-token-demo-websocket</module>
|
<module>sa-token-demo-websocket</module>
|
||||||
<module>sa-token-demo-websocket-spring</module>
|
<module>sa-token-demo-websocket-spring</module>
|
||||||
|
<module>sa-token-demo-loveqq-boot</module>
|
||||||
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
74
sa-token-demo/sa-token-demo-loveqq-boot/pom.xml
Normal file
74
sa-token-demo/sa-token-demo-loveqq-boot/pom.xml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.kfyty</groupId>
|
||||||
|
<artifactId>loveqq-framework</artifactId>
|
||||||
|
<version>1.1.2</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>sa-token-demo-loveqq-boot</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jdk.version>17</jdk.version>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<maven.source.version>17</maven.source.version>
|
||||||
|
<maven.compile.version>17</maven.compile.version>
|
||||||
|
<sa-token.version>1.43.0</sa-token.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- 引导启动模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kfyty</groupId>
|
||||||
|
<artifactId>loveqq-boot</artifactId>
|
||||||
|
<version>${loveqq.framework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- reactor-netty 服务器,同时支持命令式/响应式编程范式 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kfyty</groupId>
|
||||||
|
<artifactId>loveqq-boot-starter-netty</artifactId>
|
||||||
|
<version>${loveqq.framework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- sa-token 集成 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-loveqq-boot-starter</artifactId>
|
||||||
|
<version>${sa-token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- logback 启动器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kfyty</groupId>
|
||||||
|
<artifactId>loveqq-boot-starter-logback</artifactId>
|
||||||
|
<version>${loveqq.framework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- yaml 支持,默认使用 properties 文件,如果使用 yaml 需自行引入依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.10.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.pj;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
import com.kfyty.loveqq.framework.boot.K;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.autoconfig.annotation.EnableWebMvc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token 整合 loveqq-framework 示例
|
||||||
|
*
|
||||||
|
* @author kfyty725
|
||||||
|
*/
|
||||||
|
@EnableWebMvc
|
||||||
|
@BootApplication
|
||||||
|
public class SaTokenLoveqqApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
K.run(SaTokenLoveqqApplication.class, args);
|
||||||
|
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.pj.satoken;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||||
|
import cn.dev33.satoken.loveqq.boot.utils.SaTokenContextUtil;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.filter.Filter;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.filter.FilterChain;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.http.ServerRequest;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义过滤器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class MyFilter implements Filter {
|
||||||
|
/**
|
||||||
|
* 实现该方法,可以实现 servlet/reactor 的统一
|
||||||
|
* 但是该方法内部是同步方法,若需要异步,可以实现仅 reactor 支持的 {@link Filter#doFilter(ServerRequest, ServerResponse, FilterChain)} 方法
|
||||||
|
*
|
||||||
|
* @param request 请求
|
||||||
|
* @param response 响应
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Continue doFilter(ServerRequest request, ServerResponse response) {
|
||||||
|
System.out.println("进入自定义过滤器");
|
||||||
|
|
||||||
|
// 先 set 上下文,再调用 Sa-Token 同步 API,并在 finally 里清除上下文
|
||||||
|
SaTokenContextModelBox prev = SaTokenContextUtil.setContext(request, response);
|
||||||
|
try {
|
||||||
|
System.out.println(StpUtil.isLogin());
|
||||||
|
} finally {
|
||||||
|
SaTokenContextUtil.clearContext(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Continue.TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.pj.satoken;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.loveqq.boot.filter.SaRequestFilter;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Bean;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Sa-Token 权限认证] 配置类
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SaTokenConfigure {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册 [sa-token全局过滤器]
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public SaRequestFilter getSaReactorFilter() {
|
||||||
|
return new SaRequestFilter()
|
||||||
|
// 指定 [拦截路由]
|
||||||
|
.addInclude("/**")
|
||||||
|
// 指定 [放行路由]
|
||||||
|
.addExclude("/favicon.ico")
|
||||||
|
// 指定[认证函数]: 每次请求执行
|
||||||
|
.setAuth(r -> {
|
||||||
|
System.out.println("---------- sa全局认证");
|
||||||
|
// SaRouter.match("/test/test", () -> StpUtil.checkLogin());
|
||||||
|
})
|
||||||
|
// 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
|
||||||
|
.setError(e -> {
|
||||||
|
System.out.println("---------- sa全局异常 ");
|
||||||
|
e.printStackTrace();
|
||||||
|
return SaResult.error(e.getMessage());
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.pj.satoken;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpInterface;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义权限验证接口扩展
|
||||||
|
*/
|
||||||
|
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
|
||||||
|
public class StpInterfaceImpl implements StpInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个账号所拥有的权限码集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||||
|
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
list.add("101");
|
||||||
|
list.add("user-add");
|
||||||
|
list.add("user-delete");
|
||||||
|
list.add("user-update");
|
||||||
|
list.add("user-get");
|
||||||
|
list.add("article-get");
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个账号所拥有的角色标识集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getRoleList(Object loginId, String loginType) {
|
||||||
|
// 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
list.add("admin");
|
||||||
|
list.add("super-admin");
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.ExceptionHandler;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理
|
||||||
|
*/
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalException {
|
||||||
|
|
||||||
|
@ExceptionHandler
|
||||||
|
public SaResult handlerException(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return SaResult.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.loveqq.boot.context.SaReactorHolder;
|
||||||
|
import cn.dev33.satoken.loveqq.boot.utils.SaTokenContextUtil;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.GetMapping;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.RequestMapping;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.bind.CookieValue;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.annotation.bind.RequestParam;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.http.ServerRequest;
|
||||||
|
import com.kfyty.loveqq.framework.web.core.http.ServerResponse;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试专用Controller
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/test/")
|
||||||
|
public class TestController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserService userService;
|
||||||
|
|
||||||
|
// 登录测试:Controller 里调用 Sa-Token API --- http://localhost:8081/test/login
|
||||||
|
@GetMapping("login")
|
||||||
|
public Mono<SaResult> login(@RequestParam(defaultValue = "10001") String id) {
|
||||||
|
return SaReactorHolder.sync(() -> {
|
||||||
|
StpUtil.login(id);
|
||||||
|
return SaResult.ok("登录成功");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:手动设置上下文、try-finally 形式 --- http://localhost:8081/test/isLogin
|
||||||
|
@GetMapping("isLogin")
|
||||||
|
public SaResult isLogin(ServerRequest request, ServerResponse response) {
|
||||||
|
try {
|
||||||
|
SaTokenContextUtil.setContext(request, response);
|
||||||
|
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
} finally {
|
||||||
|
SaTokenContextUtil.clearContext(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:手动设置上下文、lambda 表达式形式 --- http://localhost:8081/test/isLogin2
|
||||||
|
@GetMapping("isLogin2")
|
||||||
|
public SaResult isLogin2(ServerRequest request, ServerResponse response) {
|
||||||
|
SaResult res = SaTokenContextUtil.setContext(request, response, () -> {
|
||||||
|
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
});
|
||||||
|
return SaResult.data(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:自动设置上下文、lambda 表达式形式 --- http://localhost:8081/test/isLogin3
|
||||||
|
@GetMapping("isLogin3")
|
||||||
|
public Mono<SaResult> isLogin3() {
|
||||||
|
return SaReactorHolder.sync(() -> {
|
||||||
|
System.out.println("是否登录:" + StpUtil.isLogin());
|
||||||
|
userService.isLogin();
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:自动设置上下文、调用 userService Mono 方法 --- http://localhost:8081/test/isLogin4
|
||||||
|
@GetMapping("isLogin4")
|
||||||
|
public Mono<SaResult> isLogin4() {
|
||||||
|
return userService.findUserIdByNamePwd("ZhangSan", "123456")
|
||||||
|
.flatMap(userId -> SaReactorHolder.sync(() -> {
|
||||||
|
StpUtil.login(userId);
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:切换线程、复杂嵌套调用 --- http://localhost:8081/test/isLogin5
|
||||||
|
@GetMapping("isLogin5")
|
||||||
|
public Mono<SaResult> isLogin5() {
|
||||||
|
System.out.println("线程id-----" + Thread.currentThread().getId());
|
||||||
|
// 要点:在流里调用 Sa-Token API 之前,必须用 SaReactorHolder.sync( () -> {} ) 进行包裹
|
||||||
|
return Mono.delay(Duration.ofSeconds(1))
|
||||||
|
.doOnNext(r -> System.out.println("线程id-----" + Thread.currentThread().getId()))
|
||||||
|
.map(r -> SaReactorHolder.sync(() -> userService.isLogin()))
|
||||||
|
.map(r -> userService.findUserIdByNamePwd("ZhangSan", "123456"))
|
||||||
|
.map(r -> SaReactorHolder.sync(() -> userService.isLogin()))
|
||||||
|
.flatMap(isLogin -> {
|
||||||
|
System.out.println("是否登录 " + isLogin);
|
||||||
|
return SaReactorHolder.sync(() -> {
|
||||||
|
System.out.println("是否登录 " + StpUtil.isLogin());
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// API测试:使用上下文无关的API --- http://localhost:8081/test/isLogin6
|
||||||
|
@GetMapping("isLogin6")
|
||||||
|
public SaResult isLogin6(@CookieValue("satoken") String satoken) {
|
||||||
|
System.out.println("token 为:" + satoken);
|
||||||
|
System.out.println("登录人:" + StpUtil.getLoginIdByToken(satoken));
|
||||||
|
return SaResult.ok("登录人:" + StpUtil.getLoginIdByToken(satoken));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||||
|
@GetMapping("test")
|
||||||
|
public SaResult test() {
|
||||||
|
System.out.println("线程id------- " + Thread.currentThread().getId());
|
||||||
|
return SaResult.ok();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Service;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模拟 Service 方法
|
||||||
|
* @author click33
|
||||||
|
* @since 2025/4/6
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
public boolean isLogin() {
|
||||||
|
System.out.println("UserService 里调用 API 测试,是否登录:" + StpUtil.isLogin());
|
||||||
|
return StpUtil.isLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Long> findUserIdByNamePwd(String name, String pwd) {
|
||||||
|
// ...
|
||||||
|
return Mono.just(10001L);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
# 端口
|
||||||
|
k:
|
||||||
|
server:
|
||||||
|
port: 8081
|
Loading…
Reference in New Issue
Block a user