- 鉴权-不用网关也可以很优雅
- 前言
- 不废话直接上代码
- 自定义注解
- 注解属性赋值 类型枚举
- 注解的具体切面逻辑
- 使用示例代码
关于鉴权,程序猿/程序媛 或多或少肯定遇到过;最基础的方式就是,我们在每个需要鉴权的地方,手写代码;然后需要的地方 copy 或者 引用使用。有些伙伴可能 想说:”网关就可以很优雅的实现“(此处我们在不依赖网关的情况 更轻量的实现)
不废话直接上代码基于spring AOP 实现(关于AOP的使用可以参考我前边文章手把手教你springboot下 AOP切面编程)
自定义注解元注解可参考(我之前的文章 元注解详解)
import java.lang.annotation.documented;
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)
public @interface Permission {
SourceType sourceType() default SourceType.WECHAT;
}
注解属性赋值 类型枚举
package com.beauty.wechat.annotation;
import lombok.Data;
public enum SourceType {
WECHAT,
OPEN;
}
注解的具体切面逻辑
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Aspect
@Component
public class PermissionAspect {
// 注解声明切点,注解的全限定名
@Pointcut("@annotation(com.beauty.wechat.annotation.Permission)")
public void annotationPointcut() {
}
@Around("annotationPointcut()&& @annotation(permission)")
public Object interceptor(ProceedingJoinPoint proceedingJoinPoint, Permission permission) {
final ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (servletRequestAttributes == null) {
return ResponseEntity.internalServerError();
}
HttpServletRequest request = servletRequestAttributes.getRequest();
String token = request.getHeader("token");
final SourceType sourceType = permission.sourceType();
boolean hasPermission = false;
switch (sourceType) {
case WECHAT:
hasPermission = hasWeChatPermission(token);
break;
case OPEN:
hasPermission = hasOpenPermission(token);
break;
default:
break;
}
if (hasPermission) {
try {
return proceedingJoinPoint.proceed();
} catch (Throwable e) {
log.warn(String.valueOf(e));
}
}
return ResponseEntity.internalServerError();
}
private Boolean hasWeChatPermission(String token) {
if (!StringUtils.hasLength(token)) {
log.info("wechat 鉴权不通过");
return false;
}
log.info("wechat 鉴权通过");
// 鉴权逻辑 根据个人业务实现
return true;
}
private Boolean hasOpenPermission(String token) {
if (!StringUtils.hasLength(token)) {
log.info("open 鉴权不通过");
return false;
}
log.info("open 鉴权通过");
// 鉴权逻辑 根据个人业务实现
return true;
}
}
使用示例代码
import com.beauty.wechat.annotation.Permission;
import com.beauty.wechat.annotation.SourceType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Permission(sourceType = SourceType.WECHAT)
@GetMapping("/test")
public String test(){
return "hello";
}
}
结果:
2021-10-31 15:38:46.062 INFO 5871 --- [p-nio-80-exec-1] c.b.w.a.aspect.PermissionAspect : wechat 鉴权通过
个人水平有限,如有问题,请各路大神指教,虚心接纳
如果觉得有帮助,请点赞收藏,谢谢



