Skip to content

Commit

Permalink
refactor: simplify AccessLimitInterceptor and remove SpringUtil class…
Browse files Browse the repository at this point in the history
… which counters Spring pattern
  • Loading branch information
Handiwork committed Feb 21, 2024
1 parent 1a66556 commit 901e3bd
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 165 deletions.
40 changes: 0 additions & 40 deletions src/main/kotlin/plus/maa/backend/common/utils/SpringUtil.kt

This file was deleted.

7 changes: 0 additions & 7 deletions src/main/kotlin/plus/maa/backend/config/CorsConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package plus.maa.backend.config

import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import plus.maa.backend.handler.AccessLimitInterceptHandlerImpl

/**
* @author AnselYuki
Expand All @@ -21,9 +19,4 @@ class CorsConfig : WebMvcConfigurer {
.allowedHeaders("*") // 跨域允许时间
.maxAge(3600)
}


override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(AccessLimitInterceptHandlerImpl())
}
}
8 changes: 2 additions & 6 deletions src/main/kotlin/plus/maa/backend/config/JacksonConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@ import org.springframework.boot.autoconfigure.jackson.JacksonProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import java.io.IOException
import java.time.*
import java.time.format.DateTimeFormatter

@Configuration
class JacksonConfig(private val jacksonProperties: JacksonProperties) : WebMvcConfigurer {
class JacksonConfig(private val jacksonProperties: JacksonProperties) {
@Bean
fun jsonCustomizer(): Jackson2ObjectMapperBuilderCustomizer {
return Jackson2ObjectMapperBuilderCustomizer { builder: Jackson2ObjectMapperBuilder ->
val format = jacksonProperties.dateFormat
val timeZone = jacksonProperties.timeZone

builder.simpleDateFormat(format)

val formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(timeZone.id))
val formatter = DateTimeFormatter.ofPattern(format).withZone(timeZone.toZoneId())
builder.serializers(LocalDateTimeSerializer(formatter))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package plus.maa.backend.common.annotation
package plus.maa.backend.config.accesslimit

import java.lang.annotation.Inherited

Expand All @@ -19,11 +19,11 @@ import java.lang.annotation.Inherited
)
annotation class AccessLimit(
/**
* 指定second 时间内,API最多的请求次数
* 指定 second 时间内,API 最多的请求次数
*/
val times: Int = 3,
/**
* 指定时间second,redis数据过期时间
* 指定时间 second,redis 数据过期时间
*/
val second: Int = 10
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package plus.maa.backend.config.accesslimit

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Configuration
class AccessLimitConfig(
private val stringRedisTemplate: StringRedisTemplate,
private val objectMapper: ObjectMapper,
) : WebMvcConfigurer {

override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(AccessLimitInterceptor(stringRedisTemplate, objectMapper))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package plus.maa.backend.config.accesslimit

import com.fasterxml.jackson.databind.ObjectMapper
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.http.HttpStatus
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.HandlerInterceptor
import plus.maa.backend.common.utils.IpUtil
import plus.maa.backend.common.utils.WebUtils
import plus.maa.backend.controller.response.MaaResult.Companion.fail
import java.util.concurrent.TimeUnit

/**
* @author Baip1995
*/
class AccessLimitInterceptor(
private val stringRedisTemplate: StringRedisTemplate,
private val objectMapper: ObjectMapper,
) : HandlerInterceptor {

private val log = KotlinLogging.logger { }

@Throws(Exception::class)
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
val ann = (handler as? HandlerMethod)?.method?.getAnnotation(AccessLimit::class.java) ?: return true
// 拼接 redis key = IP + Api 限流
val key = IpUtil.getIpAddr(request) + request.requestURI

// 获取 redis 的 value
val count = stringRedisTemplate.opsForValue()[key]?.toInt() ?: 0
if (count < ann.times) {
// 如果 redis 中的时间比注解上的时间小则表示可以允许访问,这时修改 redis 的 value 时间
stringRedisTemplate.opsForValue().set(
key,
(count + 1).toString(),
ann.second.toLong(),
TimeUnit.SECONDS
)
} else {
// 请求过于频繁
log.info { "$key 请求过于频繁" }
val result = fail(HttpStatus.TOO_MANY_REQUESTS.value(), "请求过于频繁")
val json = objectMapper.writeValueAsString(result)
WebUtils.renderString(response, json, HttpStatus.TOO_MANY_REQUESTS.value())
return false
}

return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import jakarta.validation.Valid
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import plus.maa.backend.common.annotation.AccessLimit
import plus.maa.backend.config.accesslimit.AccessLimit
import plus.maa.backend.config.doc.RequireJwt
import plus.maa.backend.config.security.AuthenticationHelper
import plus.maa.backend.controller.response.MaaResult
Expand Down

This file was deleted.

0 comments on commit 901e3bd

Please sign in to comment.