内容列表
1. Maven依赖
pom.xml引入maven依赖。
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2. Kaptcha配置类
@Configuration
class KaptchaConfig {
@Bean
fun producer(): DefaultKaptcha {
val properties = Properties()
properties.setProperty("kaptcha.border.color", "0,128,128")
properties.setProperty("kaptcha.textproducer.font.color", "14,110,184")
properties.setProperty("kaptcha.image.width", "92")
properties.setProperty("kaptcha.image.height", "46")
properties.setProperty("kaptcha.textproducer.font.size", "34")
properties.setProperty("kaptcha.textproducer.char.length", "4")
val config = Config(properties)
val defaultKaptcha = DefaultKaptcha()
defaultKaptcha.config = config
return defaultKaptcha
}
}
2.1 Kaptcha 详细配置表
Constant | 描述 | 默认值 |
---|---|---|
kaptcha.border | 图片边框,合法值:yes , no | yes |
kaptcha.border.color | 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue. | black |
kaptcha.image.width | 图片宽 | 200 |
kaptcha.image.height | 图片高 | 50 |
kaptcha.producer.impl | 图片实现类 | com.google.code.kaptcha.impl.DefaultKaptcha |
kaptcha.textproducer.impl | 文本实现类 | com.google.code.kaptcha.text.impl.DefaultTextCreator |
kaptcha.textproducer.char.string | 文本集合,验证码值从此集合中获取 | abcde2345678gfynmnpwx |
kaptcha.textproducer.char.length | 验证码长度 | 5 |
kaptcha.textproducer.font.names | 字体 | Arial, Courier |
kaptcha.textproducer.font.size | 字体大小 | 40px. |
kaptcha.textproducer.font.color | 字体颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.textproducer.char.space | 文字间隔 | 2 |
kaptcha.noise.impl | 干扰实现类 | com.google.code.kaptcha.impl.DefaultNoise |
kaptcha.noise.color | 干扰 颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.obscurificator.impl |
图片样式: 水纹 com.google.code.kaptcha.impl.WaterRipple 鱼眼 com.google.code.kaptcha.impl.FishEyeGimpy 阴影 com.google.code.kaptcha.impl.ShadowGimpy |
com.google.code.kaptcha.impl.WaterRipple |
kaptcha.background.impl | 背景实现类 | com.google.code.kaptcha.impl.DefaultBackground |
kaptcha.background.clear.from | 背景颜色渐变,开始颜色 | light grey |
kaptcha.background.clear.to | 背景颜色渐变, 结束颜色 | white |
kaptcha.word.impl | 文字渲染器 | com.google.code.kaptcha.text.impl.DefaultWordRenderer |
kaptcha.session.key | session key | KAPTCHA_SESSION_KEY |
kaptcha.session.date | session date | KAPTCHA_SESSION_DATE |
3. Captcha实体类
captcha存储在数据库中。
@Entity
data class Captcha(
@Column(nullable = false) val name: String,
@Column(nullable = false) val code: String,
@Column(nullable = false) val expireTime: Instant,
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Int? = null
)
4. Captcha仓库类
Spring Data JPA仓库类读取数据。
interface CaptchaRepository : JpaRepository<Captcha, Int> {
fun findByName(name: String): Captcha?
fun deleteAllByName(name: String)
}
5. Captcha控制器
生成验证码图片返回给前端。
@Controller
@RequestMapping("/captcha")
class CaptchaController(private val service: CaptchaService) {
@GetMapping
fun generate(name: String, response: HttpServletResponse) = service.generate(name, response)
}
6.Captcha服务类
生成验证码和验证。
@Service
class CaptchaService(private val repository: CaptchaRepository, private val kaptchaProducer: DefaultKaptcha) {
@Transactional
fun generate(name: String, response: HttpServletResponse) {
val code = kaptchaProducer.createText()
val image: BufferedImage = kaptchaProducer.createImage(code)
repository.deleteAllByName(name)
repository.save(Captcha(name, code, Instant.now().plusSeconds(60)))
response.contentType = MediaType.IMAGE_JPEG_VALUE
ImageIO.write(image, "jpg", response.outputStream)
}
fun validate(name: String, code: String?): Boolean {
val captcha = repository.findByName(name) ?: return false
if (Instant.now().isAfter(captcha.expireTime)) {
repository.delete(captcha)
return false
}
if (captcha.code == code) {
repository.delete(captcha)
return true
}
return false
}
}
7. 验证验证码
override fun preLogin(account: LoginDto) {
val ip = getClientIp()
val user = userRepository.findByUsername(account.username)
val key = if (user == null) "$ip" else "${user.id}-$ip"
val count = cache.getIfPresent(key) ?: 0
if (count > 5 && !captchaService.validate(account.username, account.captcha)) {
throw AppUnauthorizedException("验证码错误")
}
}