springboot整合kaptcha验证码实现前后端分离项目的验证码验证。

公良同
2023-12-01

主要思路:因为是前后端分离,所以后端生成的验证码不能通过session直接拿到,所以后端生成的验证码会保存在redis中,前端登录时带上key和value,后端根据Key去redis取值,再和前端传进来的value对比,完成验证码验证。

1、添加 kaptcha的引用

        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

2、添加kaptcha的配置文件

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Properties;

@Component
public class KaptcharConfig {

	@Bean
	public DefaultKaptcha getDefaultKaptcha() {

		com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
		Properties properties = new Properties();
		properties.setProperty("kaptcha.border", "yes");
		properties.setProperty("kaptcha.border.color", "105,179,90");
		properties.setProperty("kaptcha.textproducer.font.color", "blue");
		properties.setProperty("kaptcha.image.width", "110");
		properties.setProperty("kaptcha.image.height", "40");
		properties.setProperty("kaptcha.textproducer.font.size", "30");
		properties.setProperty("kaptcha.session.key", "code");
		properties.setProperty("kaptcha.textproducer.char.length", "4");
		properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
		Config config = new Config(properties);
		defaultKaptcha.setConfig(config);

		return defaultKaptcha;
	}
}

3、登录接口

    @PostMapping(value = "/login")
    public JSONResult login(@RequestParam("userName") String userName,
                            @RequestParam("passWord") String passWord,
                            @RequestParam("cToken") String cToken,
                            @RequestParam("verifyCode") String verifyCode) throws DeviceCloudException {

在接口内取redis的value进行比较。

4、获取验证码的接口

    @Autowired
    private DefaultKaptcha producer;    

    @ApiOperation(value = "获取验证码",notes= "获取验证码的接口")
    @GetMapping(value = "/default")
    public JSONResult generateVerificationCode() throws Exception {
        Map<String, Object> map = new HashMap<>();
        // 生成文字验证码
        String text = producer.createText();
        // 生成图片验证码
        ByteArrayOutputStream outputStream = null;
        BufferedImage image = producer.createImage(text);
        outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);
        //
        BASE64Encoder encoder = new BASE64Encoder();
        String imageStr=encoder.encode(outputStream.toByteArray());
        map.put("img",imageStr );
        //生成验证码对应的token  以token为key  验证码为value存在redis中
        String codeToken = NumberUtil.getStringRandom(16);
        redisTemplate.opsForValue().set(codeToken, text, RedisConstant.VERIFY_CODE_EXPIRE_TIME, TimeUnit.MINUTES);
        map.put("cToken", codeToken);
        return JSONResult.ok(map);
    }

注意,这里返回前端的是转成base64的图片,前端需要这样显示:

<img src="https://img-blog.csdnimg.cn/2022010710301536896.png"/>

 

 类似资料: