注解实现接口鉴权和防刷限制
- 步骤
- 1. 自定义注解
- 2. 自定义Interceptor
- 3. 拦截器注入Springboot
- 4. 使用
项目中需要对开放给第三方接口实现鉴权和防刷限制可以使用自定义注解和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 {@Autowiredprivate RedisTemplate<String,Integer> redisTemplate;@Overridepublic 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 注入RedisTemplateboolean 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){//加1redisTemplate.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;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(interceptor);}
}
4. 使用
@AccessLimit@RequestMapping("/save")public String save(User users) {return users.toString();}