注解实现接口鉴权和防刷限制


项目中需要对开放给第三方接口实现鉴权和防刷限制可以使用自定义注解和Interceptor来实现

步骤

1. 自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {

    int seconds() default 1;
    int maxCount() default 1;
    boolean needLogin()default true;
}

2. 自定义Interceptor

@Component
public class InterfaceInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String,Integer> redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //是否方法请求
        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            //方法上是否有注解
            AccessLimit methodAnnotation = hm.getMethodAnnotation(AccessLimit.class);
            if(methodAnnotation == null){
                return true;
            }
            int maxCount = methodAnnotation.maxCount();
            int seconds = methodAnnotation.seconds();
            //TODO 注入RedisTemplate

            boolean needLogin = methodAnnotation.needLogin();
            if(needLogin){
                //判断登陆,接口授权的秘钥
                String secertKey = request.getParameter("secertKey");
                if(StringUtils.hasText(secertKey)){
                    //查询数据库判断
                    return true;
                }else{
                    render(response,"未登录");
                    return false;
                }
            }
            String key = request.getRequestURI();
            //从redis中获取用户访问的次数
            Integer count = redisTemplate.opsForValue().get(key);
            if(count == null){
                //第一次访问
                redisTemplate.opsForValue().set(key,1);
                redisTemplate.expire(key,seconds, TimeUnit.SECONDS);
            }else if(count < maxCount){
                //加1
                redisTemplate.boundValueOps(key).increment();
                redisTemplate.expire(key,seconds, TimeUnit.SECONDS);
            }else{
                //超出访问次数
                render(response,"超出访问次数,请稍后重试"); //这里的CodeMsg是一个返回参数
                return false;
            }

        }
        return true;
    }

    private static void render(HttpServletResponse response,String str) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        out.write(str.getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();
    }
}

3. 拦截器注入Springboot

@Configuration
@RequiredArgsConstructor
public class InterfaceConfig implements WebMvcConfigurer {
    private final InterfaceInterceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor);
    }
}

4. 使用

 @AccessLimit
 @RequestMapping("/save")
 public String save(User users) {
     return users.toString();
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值