ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

登录注解aop

2022-06-06 15:02:39  阅读:171  来源: 互联网

标签:lang 登录 org aop public import 注解 annotation aspectj


登录注解aop

资料参考地址1: spring-AOP 及 AOP获取request各项参数操作

需求: 通过请求头中的token查询用户信息,存放到ThreadLocal中

注意:有许多接口对外开放,不可用统一拦截器来验证是否登录

登录注解

/**
 * 登录注解
 * @author lyn
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequiredLogin {
    /**
     * 是否必须登录,默认true,false为测试用,如果值为false且使用了UserHandler,会抛出空指针异常
     * @return
     */
    boolean isRequiredLogin() default true;
}

登录aop

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

/**
 * 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();
    }

}

 

标签:lang,登录,org,aop,public,import,注解,annotation,aspectj
来源: https://www.cnblogs.com/lyn8100/p/16348206.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有