网站首页 > 技术文章 正文
每次新项目启动,接口鉴权都让你头疼?重复的token校验代码散落在各个Controller里,每次权限变更都要改几十个地方?今天教你用一个注解终结混乱!
痛苦面具:传统鉴权有多糟?
@RestController
public class OrderController {
@GetMapping("/order")
public ResponseEntity<Order> getOrder(@RequestHeader("Authorization") String token) {
// 每个接口都要重复写这段校验!
if (!TokenUtils.validateToken(token)) {
throw new UnauthorizedException("无效Token");
}
// 真正的业务逻辑
return orderService.getOrder();
}
}
痛点直击:
- 重复代码泛滥:每个接口都要写token校验
- 业务逻辑污染:核心逻辑被鉴权代码淹没
- 维护噩梦:修改鉴权逻辑需改动所有接口
神级解决方案:自定义注解 + 拦截器
第一步:创建你的魔法注解@LoginRequired
@Target(ElementType.METHOD) // 注解用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
public @interface LoginRequired {
boolean required() default true; // 默认需要登录
}
第二步:打造全局拦截器
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 1. 检查是否需要登录
if (!(handler instanceof HandlerMethod)) return true;
HandlerMethod hm = (HandlerMethod) handler;
LoginRequired annotation = hm.getMethodAnnotation(LoginRequired.class);
// 2. 无注解直接放行
if (annotation == null || !annotation.required()) return true;
// 3. 执行统一鉴权(核心逻辑!)
String token = request.getHeader("Authorization");
if (TokenUtils.isValid(token)) {
return true; // 验证通过
}
// 4. 拦截非法请求
response.setStatus(401);
throw new BusinessException(401, "请先登录");
}
}
第三步:注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**"); // 拦截所有路径
}
}
效果对比:解放双手的魔法时刻
改造前:每个接口手动校验
@GetMapping("/user/profile")
public UserProfile getProfile(@RequestHeader String token) {
if(!checkToken(token)) throw new AuthException();
return userService.getProfile();
}
改造后:一行注解搞定
@LoginRequired // 只需添加这个注解
@GetMapping("/user/profile")
public UserProfile getProfile() {
// 纯净的业务逻辑!
return userService.getProfile();
}
进阶技巧:支持角色权限控制
// 扩展注解支持角色
@LoginRequired(roles = {"ADMIN", "MANAGER"})
// 拦截器中追加校验
if (annotation != null) {
User user = TokenUtils.parseUser(token);
if (!user.hasRoles(annotation.roles())) {
throw new ForbiddenException("权限不足");
}
}
为什么这个方案能引爆效率?
- 关注点分离:鉴权与业务代码彻底解耦
- 零侵入改造:老接口只需添加注解
- 统一管控:所有鉴权逻辑集中处理
- 灵活扩展:轻松支持RBAC等复杂场景
实测某电商项目:
- 鉴权代码量减少 82%
- 权限变更时间从 3小时→5分钟
- 接口bug率下降 70%
行动号召:立即升级你的鉴权方案!
// 今天就开始用这个注解!
@LoginRequired
@PostMapping("/secure/endpoint")
public ResponseEntity<?> sensitiveOperation() {
// 专注写业务代码吧!
}
技术栈清单:
- Spring Boot 2.7+
- Java 17(兼容JDK8+)
- 无需额外依赖!
经验之谈:对于内部管理系统,可搭配 @LoginRequired(required=false) 实现部分接口免登录,灵活性拉满!
记住:优雅的代码不是没有逻辑,而是让逻辑出现在该出现的地方。 用好自定义注解,让你的鉴权方案从“能用”跃升到“优雅”!
猜你喜欢
- 2025-07-28 如何优雅的实现 Spring Boot 接口参数加密解密?
- 2025-07-28 SpringBoot注解最全详解(9大常用注解)
- 2025-07-28 SpringBoot注解全攻略:这些注解让你的代码更专业!
- 2025-07-28 后端使用技术 —— 规范统一入口方法
- 2025-07-28 答应我,不要再用 Map 做出入参了好吗
- 2025-07-28 关于远程调用feign的优雅写法(feign远程调用怎么用restful)
- 2025-07-28 自研分布式高性能RPC框架及服务注册中心ApiRegistry实践笔记
- 2025-07-28 spring基础面试题整理(2)(spring基本面试题)
- 2025-07-28 Spring Boot异常处理太难搞,这样实现让你轻松应对!
- 2025-07-28 独立开发:高效集成大模型,看这篇就够了
- 1518℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 602℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 522℃MySQL service启动脚本浅析(r12笔记第59天)
- 490℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 489℃启用MySQL查询缓存(mysql8.0查询缓存)
- 477℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 457℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 454℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)