欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-20 21:27:28
...

主要思路:因为是前后端分离,所以后端生成的验证码不能通过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="data:image/png;base64,此处填base64编码"/>