From 56ed3aa32a64835c9053d734323079d2c1d8062f Mon Sep 17 00:00:00 2001 From: Kairos <2990566096@qq.com> Date: Mon, 9 Jun 2025 13:56:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(sa-token-core):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=20SaCheckOrHandler=20=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -将 checkMethod 方法中的逻辑抽取到新的 _checkMethod 方法中 - 新增 _annotationList 方法,用于获取注解列表 - 优化代码结构,提高可读性和可维护性 --- .../annotation/handler/SaCheckOrHandler.java | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckOrHandler.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckOrHandler.java index 5c2566c7..ab79a71b 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckOrHandler.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckOrHandler.java @@ -15,7 +15,7 @@ */ package cn.dev33.satoken.annotation.handler; -import cn.dev33.satoken.annotation.*; +import cn.dev33.satoken.annotation.SaCheckOr; import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.strategy.SaAnnotationStrategy; @@ -40,38 +40,15 @@ public class SaCheckOrHandler implements SaAnnotationHandlerInterface @Override public void checkMethod(SaCheckOr at, AnnotatedElement element) { - _checkMethod(at.login(), at.role(), at.permission(), at.safe(), at.httpBasic(), at.httpDigest(), at.disable(), at.append(), element); + _checkMethod(at, element); } - public static void _checkMethod( - SaCheckLogin[] login, - SaCheckRole[] role, - SaCheckPermission[] permission, - SaCheckSafe[] safe, - SaCheckHttpBasic[] httpBasic, - SaCheckHttpDigest[] httpDigest, - SaCheckDisable[] disable, - Class[] append, - AnnotatedElement element - ) { + public static void _checkMethod(SaCheckOr at, AnnotatedElement element) { // 先把所有注解塞到一个 list 里 - List annotationList = new ArrayList<>(); - annotationList.addAll(Arrays.asList(login)); - annotationList.addAll(Arrays.asList(role)); - annotationList.addAll(Arrays.asList(permission)); - annotationList.addAll(Arrays.asList(safe)); - annotationList.addAll(Arrays.asList(disable)); - annotationList.addAll(Arrays.asList(httpBasic)); - annotationList.addAll(Arrays.asList(httpDigest)); - for (Class annotationClass : append) { - Annotation annotation = SaAnnotationStrategy.instance.getAnnotation.apply(element, annotationClass); - if(annotation != null) { - annotationList.add(annotation); - } - } + List annotationList = _annotationList(at, element); // 如果 atList 为空,说明 SaCheckOr 上不包含任何注解校验,我们直接跳过即可 - if(annotationList.isEmpty()) { + if (annotationList.isEmpty()) { return; } @@ -91,4 +68,26 @@ public class SaCheckOrHandler implements SaAnnotationHandlerInterface throw errorList.get(0); } + /** + * 返回注解List供外部调用使用,例如增加SaCheckApiKey的或校验 + */ + public static List _annotationList(SaCheckOr or, AnnotatedElement element) { + List annotationList = new ArrayList<>(); + annotationList.addAll(Arrays.asList(or.login())); + annotationList.addAll(Arrays.asList(or.role())); + annotationList.addAll(Arrays.asList(or.permission())); + annotationList.addAll(Arrays.asList(or.safe())); + annotationList.addAll(Arrays.asList(or.disable())); + annotationList.addAll(Arrays.asList(or.httpBasic())); + annotationList.addAll(Arrays.asList(or.httpDigest())); + for (Class annotationClass : or.append()) { + Annotation annotation = SaAnnotationStrategy.instance.getAnnotation.apply(element, annotationClass); + if (annotation != null) { + annotationList.add(annotation); + } + } + + return annotationList; + } + } \ No newline at end of file -- Gitee From f76afa7de6674db3e27ce3344c4015565dddd4e2 Mon Sep 17 00:00:00 2001 From: Kairos <2990566096@qq.com> Date: Mon, 9 Jun 2025 13:59:44 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(apikey):=20=E6=B7=BB=E5=8A=A0=20SaChec?= =?UTF-8?q?kApiKeyOr=20=E6=B3=A8=E8=A7=A3=E5=92=8C=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 SaCheckApiKeyOr 注解,用于在 API Key 验证中实现"或者"的逻辑。同时添加 SaCheckApiKeyOrHandler 处理器类,用于处理 SaCheckApiKeyOr 注解的验证逻辑。 - SaCheckApiKeyOr 注解包含 or 和 apiKey 两个属性 - SaCheckApiKeyOrHandler 实现了 SaAnnotationHandlerInterface 接口 - _checkMethod 方法实现了"或者"逻辑的验证过程 --- .../apikey/annotation/SaCheckApiKeyOr.java | 23 +++++++ .../handle/SaCheckApiKeyOrHandler.java | 61 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/SaCheckApiKeyOr.java create mode 100644 sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/handle/SaCheckApiKeyOrHandler.java diff --git a/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/SaCheckApiKeyOr.java b/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/SaCheckApiKeyOr.java new file mode 100644 index 00000000..2ad91aaa --- /dev/null +++ b/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/SaCheckApiKeyOr.java @@ -0,0 +1,23 @@ +package cn.dev33.satoken.apikey.annotation; + +import cn.dev33.satoken.annotation.SaCheckOr; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface SaCheckApiKeyOr { + + /** + * 引用SaCheckOr的配置 + */ + SaCheckOr or() default @SaCheckOr(); // 默认空配置 + + /** + * API Key 配置 + */ + SaCheckApiKey[] apiKey() default {}; +} diff --git a/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/handle/SaCheckApiKeyOrHandler.java b/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/handle/SaCheckApiKeyOrHandler.java new file mode 100644 index 00000000..bbdf5b95 --- /dev/null +++ b/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/annotation/handle/SaCheckApiKeyOrHandler.java @@ -0,0 +1,61 @@ +package cn.dev33.satoken.apikey.annotation.handle; + +import cn.dev33.satoken.annotation.*; +import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface; +import cn.dev33.satoken.annotation.handler.SaCheckOrHandler; +import cn.dev33.satoken.apikey.annotation.SaCheckApiKey; +import cn.dev33.satoken.apikey.annotation.SaCheckApiKeyOr; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.strategy.SaAnnotationStrategy; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SaCheckApiKeyOrHandler implements SaAnnotationHandlerInterface { + + @Override + public Class getHandlerAnnotationClass() { + return SaCheckApiKeyOr.class; + } + + @Override + public void checkMethod(SaCheckApiKeyOr at, AnnotatedElement element) { + // 直接调用父类的 _checkMethod 方法进行校验 + _checkMethod(at.or(),at.apiKey(),element); + } + + public static void _checkMethod( + SaCheckOr or, + SaCheckApiKey[] apiKey, + AnnotatedElement element + ) { + + // 先把所有注解塞到一个 list 里 + List annotationList = new ArrayList<>(); + annotationList.addAll(Arrays.asList(apiKey)); + annotationList.addAll(SaCheckOrHandler._annotationList(or,element)); + + // 如果 atList 为空,说明 SaCheckOr 上不包含任何注解校验,我们直接跳过即可 + if(annotationList.isEmpty()) { + return; + } + + // 逐个开始校验 >>> + List errorList = new ArrayList<>(); + for (Annotation item : annotationList) { + try { + SaAnnotationStrategy.instance.annotationHandlerMap.get(item.annotationType()).check(item, element); + // 只要有一个校验通过,就可以直接返回了 + return; + } catch (SaTokenException e) { + errorList.add(e); + } + } + + // 执行至此,说明所有注解校验都通过不了,此时 errorList 里面会有多个异常,我们随便抛出一个即可 + throw errorList.get(0); + } +} -- Gitee