统一登录spring拦截代码

  1. 登录接口返回token
  2. 请求携带header里token验证登录状态
  3. redis 返回登录时间

上代码:

yml配置:
##前端登录配置
session:
  config:
    ##是否启用
    enable: true
    ##携带key
    headerKey: api-token
    ##拦截路径逗号分割
    patterns: /shop/me/**,/me/**
    ##session超时配置
    hourTimeOut: 24

config类

@Data
@Component
public class SessionConfig {
    @Value("${session.config.hourTimeOut:24}")
    private Integer hourTimeOut;
    @Value("${session.config.enable:true}")
    private Boolean enable;
    @Value("${session.config.patterns:/**}")
    private String patterns;
    @Value("${session.config.headerKey:api-token}")
    private String headerKey;
}

用户上下文
public class LoginUserContext implements Serializable {
    private static ThreadLocal<LoginUserInfo> threadLocal =
            new ThreadLocal<>();
    public static LoginUserInfo getUserSession() {
        return threadLocal.get();
    }
    public static void setUserSession(LoginUserInfo entity) {
        threadLocal.set(entity);
    }
    public static void removeUserSession() {
        threadLocal.remove();
    }
}
用户登录
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class LoginUserInfo implements java.io.Serializable {
    private Long userId;
    private String userName;
    private String sessionKey;
}

常量
public class GlobalConstant {
    public static final String SESSION_TOKEN = "lg:token:%s";
    public static final String SESSION_USER_TOKEN = "lg:user:token:%d";
}

spring拦截器配置

@Slf4j
@Configuration
public class SessionWebConfig implements WebMvcConfigurer {
    @Autowired
    private SessionConfig sessionConfig;
    @Autowired
    private SessionInterceptor sessionInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> pathPatterns = Arrays.asList(sessionConfig.getPatterns().split(","));
        List<String> excludePathPatterns = Lists.newArrayList("/doc.html/**", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
        log.info("-----------auth session interceptor patterns-------------");
        log.info("------pathPatterns-----{}", JSON.toJSONString(pathPatterns));
        log.info("------excludePathPatterns-----{}", JSON.toJSONString(excludePathPatterns));
        registry.addInterceptor(sessionInterceptor)
                .addPathPatterns(pathPatterns)
                .excludePathPatterns(excludePathPatterns);
    }
}

不需要登录得方法注解

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
public @interface NotAuth {

}

拦截器代码

@Slf4j
@Component
public class SessionInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private SessionConfig sessionConfig;
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        LoginUserContext.removeUserSession();
        if (!sessionConfig.getEnable()) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 配置该注解,说明不进行服务拦截
        NotAuth notAuth = handlerMethod.getBeanType().getAnnotation(NotAuth.class);
        if (notAuth != null) {
            return true;
        }
        String token = request.getHeader(sessionConfig.getHeaderKey());
        LoginUserInfo loginUserInfo = null;
        if (StringUtils.isNotEmpty(token)) {
            loginUserInfo =
                    (LoginUserInfo) this.redisTemplate.opsForValue().get(
                            SessionKeyUtil.getRedisToken(token)
                    );
        }
        if (loginUserInfo == null) {
            log.error("not login token {} method {} ", token, handlerMethod.getMethod().getName());
            throw new RongTongCodeException(401, "未登录");
        }
        LoginUserContext.setUserSession(loginUserInfo);
        return true;
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoginUserContext.removeUserSession();
    }
}

登录rpc


@Component
public class UserLoginRpc {
    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private SessionConfig sessionConfig;
    /**
     * 登录接口
     *
     * @param loginUserInfo
     * @return
     */
    public String login(LoginUserInfo loginUserInfo) {
        if (loginUserInfo == null || loginUserInfo.getUserId() == null) {
            throw new RongTongCodeException(400, "登录用户参数异常");
        }
        //上个登录token有效期5分钟
        String userToken = SessionKeyUtil.getRedisUserToken(loginUserInfo.getUserId());
        String alreadyLogin = (String) this.redisTemplate.opsForValue().get(userToken);
        if (StringUtils.isNotEmpty(alreadyLogin)) {
            //已经登录的token 5分钟
            this.redisTemplate.expire(
                    SessionKeyUtil.getRedisToken(alreadyLogin),
                    5,
                    TimeUnit.MINUTES
            );
        }
        this.redisTemplate.delete(userToken);
        return this.setSession(loginUserInfo);
    }

    private String setSession(LoginUserInfo loginUserInfo) {
        String token = java.util.UUID.randomUUID().toString()
                .replaceAll("-", "");
        this.redisTemplate.opsForValue().set(
                SessionKeyUtil.getRedisToken(token), loginUserInfo
                , sessionConfig.getHourTimeOut(), TimeUnit.HOURS
        );
        this.redisTemplate.opsForValue().set(
                SessionKeyUtil.getRedisUserToken(loginUserInfo.getUserId()), token
                , sessionConfig.getHourTimeOut(), TimeUnit.HOURS
        );
        return token;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值