登录注解aop
登录注解aop
资料参考地址1:
需求:
通过请求头中的token查询用户信息,存放到ThreadLocal中
注意:
登录注解
/** * 登录注解 * @author lyn */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequiredLogin { /** * 是否必须登录,默认true,false为测试用,如果值为false且使用了UserHandler,会抛出空指针异常 * @return */ boolean isRequiredLogin() default true; }
import cn.hutool.core.util.StrUtil; import com.aliyuncs.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.cuour.account.common.constant.SystemConstants; import org.cuour.account.common.dto.SysUserDto; import org.cuour.account.common.dto.UserDetailDto; import org.cuour.account.rpc.api.CheckAuthTokenService; import org.cuour.account.rpc.api.SalesServiceRpc; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Objects; /** * 登录aop * * @author lyn * @date 2022/6/6 11:03 */ @Aspect @Component @Slf4j @Order(5) public class RequiredLoginAspect { private final static String USER_ID = "USER-ID"; /** * 令牌自定义标识 */ @Value("${token.header}") private String header; /** * 定义切点 切点为 */ @Pointcut("@annotation(org.hjxr.cc.rest.annotation.RequiredLogin)") public void pointcutLogin() { } @Before("pointcutLogin()") public void verifyLogin(JoinPoint joinPoint) { RequiredLogin requiredLogin = getAnnotationRequiredLogin(joinPoint); boolean isRequiredLogin = requiredLogin.isRequiredLogin(); if (isRequiredLogin) { // 获取原始的HttpServletRequest ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = request.getHeader(this.header); String userId = request.getHeader(USER_ID); UserDetailDto userDetailDto = null; //通过请求头中的token或者userId获取当前用户信息,省略 if (Objects.isNull(userDetailDto)) { throw new BizException(2001000000, "认证信息有误"); } UserHandler.setUserInfo(userDetailDto); } } /** * 获取注解 * * @param joinPoint * @return */ private RequiredLogin getAnnotationRequiredLogin(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(RequiredLogin.class); } throw new BizException(BizMessage.SYSTEM_EXCEPTION); } @AfterReturning(pointcut = "pointcutLogin()") public void doAfterReturning(JoinPoint joinPoint) { RequiredLogin requiredLogin = getAnnotationRequiredLogin(joinPoint); boolean isRequiredLogin = requiredLogin.isRequiredLogin(); UserHandler.removeUserInfo(); if (isRequiredLogin) { // 删除ThreadLocal中的数据,以防内存泄露问题 UserHandler.removeUserInfo(); } } }
/** * threadLocal工具类操作user对象 * @author lyn */ public class UserHandler { private static final ThreadLocal<UserDetailDto> TL = new ThreadLocal<>(); /** * 向线程内存储user * @param user */ public static void setUserInfo(UserDetailDto user) { TL.set(user); } /** * 从线程内获取user * @return */ public static UserDetailDto getUserInfo() { return TL.get(); } /** * 删除线程内user */ public static void removeUserInfo() { TL.remove(); } }