怎么在SpringBoot中使用Spring AOP实现接口鉴权
面向切面编程
面向切面编程,可以将与业务无关但是需要被各个业务模块共同调用的逻辑抽取出来,以切面的方式切入到代码中,从而降低系统中代码的耦合度,减少重复的代码。
Spring AOP是通过预编译方式和运行期间动态代理实现程序面向切面编程
AOP的底层原理实现
AOP底层使用动态代理完成需求,为需要增加增强功能的类来生成代理类,有两种生成代理类的方式,对于被代理类(即需要增强的类),如果:
实现了接口,使用JDK动态代理,生成的代理类会使用其接口没有实现接口,
使用CGlib动态代理,生成的代理类会集成被代理类
AOP的相关术语
连接点:被代理(被增强)的类中的方法
切入点:实际上需要被增强的方法
通知:要增强的逻辑代码
前置通知:在主体功能执行之前执行
后置通知:在主题功能执行之后执行
环绕通知:在主体功能执行前后执行
异常通知:在主题功能执行出现异常时执行
最终通知:主体功能无论执行是否成功都会执行
切面:切入点和切面的结合,即被增强的方法和增强的功能组成切面
相关注解以及切入点表达式
注解:
@Aspect: 声明某个类是切面,编写通知、切入点
@Before: 对应前置通知
@AfterReturning: 对应后置通知
@Around: 对应环绕通知
@AfterThrowing: 对应异常通知
@After: 对应最终通知
@Pointcut: 声明切入点,标注在一个方法上可以让表达式更简洁
使用切入点表达式声明切入点
execution([权限修饰符][返回类型][类完全路径].[方法名称][参数列表类型])
execution(* com.xxx.ABC.add()),对ABC类的方法进行增强
实现接口鉴权
1. 配置yml文件
配置接口鉴权账密
account: infos: - account: xinchao secret: admin
2. 读取账密配置
@Data public class SecretInfo { private String account; private String secret; }
3.编写接口鉴权方法
@Configuration @ConfigurationProperties("account") public class SecretConfig { private List<SecretInfo> infos; private Map<String, SecretInfo> map; private Map<String, TokenInfo> tokenMap = new HashMap<>(); public void setInfos(List<SecretInfo> infos) { this.infos = infos; map = infos.stream().collect(Collectors.toMap(SecretInfo::getAccount, Function.identity())); } public synchronized String getToken(String account, String secret) { SecretInfo info = map.get(account); if (info == null) { throw new BusinessException("无效账号"); } if (!StringUtils.equals(info.getSecret(), secret)) { throw new BusinessException("无效密码"); } TokenInfo tokenInfo = tokenMap.get(account); if (tokenInfo != null && tokenInfo.getToken() != null) { return tokenInfo.getToken(); } tokenInfo = new TokenInfo(); String uuid = UUID.randomUUID().toString(); tokenInfo.setToken(uuid); tokenInfo.setCreateDate(LocalDateTime.now()); tokenInfo.setExpireDate(LocalDateTime.now().plusHours(2)); tokenMap.put(account,tokenInfo); return tokenInfo.getToken(); } public boolean checkCaptcha(String captcha) { return tokenMap.values().stream().anyMatch(e->StringUtils.equals(e.getToken(),captcha)); } }
@Data public class TokenInfo { private LocalDateTime createDate; private LocalDateTime expireDate; private String token; public String getToken() { if (LocalDateTime.now().isBefore(expireDate)) { return token; } return null; } public boolean verification(String token) { return Objects.equals(this.token, token); } }
4. 编写AOP
首先,编写一个注解来标识不需要鉴权
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CaptchaIgnoreAop { }
@Slf4j @Aspect @Component @Order(2) public class CaptchaAop { @Value("${spring.profiles.active:dev}") private String env; @Autowired private SecretConfig config; @Pointcut("execution(public * com.herenit.phsswitch.controller.impl..*.*(..))" + "&&@annotation(org.springframework.web.bind.annotation.PostMapping)" + "&&!@annotation(com.herenit.phsswitch.aop.CaptchaIgnoreAop)") public void tokenAop() { } @Around("tokenAop()") public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); if (args.length == 0 || !(args[0] instanceof RequestWrapper) || "test,dev".contains(env)) { log.info("当前环境无需校验token"); return joinPoint.proceed(); } String captcha = ((RequestWrapper) joinPoint.getArgs()[0]).getCaptcha(); if (!config.checkCaptcha(captcha)) { throw new BusinessException("captcha无效"); } return joinPoint.proceed(); } }
5.编写接口测试
@PostMapping("/login") @CaptchaIgnoreAop public ResponseWrapper login(@RequestBody JSONObject userInfo) { String token = config.getToken(userInfo.getString("loginName") , userInfo.getString("password")); JSONObject result = new JSONObject(); result.put("platformAccessToken", token); return ResponseWrapper.success(result); }
使用此接口能够在内存中创建一个令牌,并将其返回给前端。之后我们在调其他接口时传入这个token进行鉴权即可。传入的位置是captcha字段
public class RequestWrapper<T> implements Serializable { private static final long serialVersionUID = 8988706670118918321L; public RequestWrapper() { super(); } private T args; private String captcha; private String funcode; public T getArgs() { return args; } public void setArgs(T args) { this.args = args; } public String getCaptcha() { return captcha; } public void setCaptcha(String captcha) { this.captcha = captcha; } public String getFuncode() { return funcode; } public void setFuncode(String funcode) { this.funcode = funcode; } }
以上是怎么在SpringBoot中使用Spring AOP实现接口鉴权的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

2023年,AI技术已经成为热点话题,对各行业产生了巨大影响,编程领域尤其如此。人们越来越认识到AI技术的重要性,Spring社区也不例外。随着GenAI(GeneralArtificialIntelligence)技术的不断进步,简化具备AI功能的应用程序的创建变得至关重要和迫切。在这个背景下,"SpringAI"应运而生,旨在简化开发AI功能应用程序的过程,使其变得简单直观,避免不必要的复杂性。通过"SpringAI",开发者可以更轻松地构建具备AI功能的应用程序,将其变得更加易于使用和操作

spring编程式事务的实现方式:1、使用TransactionTemplate;2、使用TransactionCallback和TransactionCallbackWithoutResult;3、使用Transactional注解;4、使用TransactionTemplate和@Transactional结合使用;5、自定义事务管理器。

Spring+AI作为行业领导者,通过其强大、灵活的API和先进的功能,为各种行业提供了领先性的解决方案。在本专题中,我们将深入探讨Spring+AI在各领域的应用示例,每个案例都将展示Spring+AI如何满足特定需求,实现目标,并将这些LESSONSLEARNED扩展到更广泛的应用。希望这个专题能对你有所启发,更深入地理解和利用Spring+AI的无限可能。Spring框架在软件开发领域已经有超过20年的历史,自SpringBoot1.0版本发布以来已有10年。现在,无人会质疑,Spring

SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

本文来写个详细的例子来说下dubbo+nacos+Spring Boot开发实战。本文不会讲述太多的理论的知识,会写一个最简单的例子来说明dubbo如何与nacos整合,快速搭建开发环境。

Spring设置事务隔离级别的方法:1、使用@Transactional注解;2、在Spring配置文件中设置;3、使用PlatformTransactionManager;4、在Java配置类中设置。详细介绍:1、使用@Transactional注解,在需要进行事务管理的类或方法上添加@Transactional注解,并在属性中设置隔离级别;2、在Spring配置文件等等。

JUnit是Spring项目中广泛使用的Java单元测试框架,可以通过以下步骤应用:添加JUnit依赖项:org.junit.jupiterjunit-jupiter5.8.1test编写测试用例:使用@ExtendWith(SpringExtension.class)启用扩展,使用@Autowired注入Bean,使用@BeforeEach和@AfterEach准备和清理,用@Test标记测试方法。

SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人
