图片验证码详解(生成/保存/发送/验证)

本文使用的图片验证码生产工具是captcha,废话不多说,直接上代码

关于前后端分离,图片如何保存验证,只需前端获取图片验证码时传入一个key,将图片存入redis时用该key作为存入redis的key,提交注册/登录时携带该key,即可。

 

Controller

/**
 * 图片验证码 控制器
 */
@RestController
@Api(value = "@-图片验证码")
@RequestMapping(value = "/admin/imagevc/")
public class ImageVcController extends ZyBaseController {

    @Autowired
    protected CaptchaService captchaService;

    /**
     * 获取图片验证码
     *
     * @return java.lang.Object
     * @author xx
     * @date 2021/3/03 10:36
     */
    @PostMapping(value = "")
    public void query(@RequestBody ImageVcIn in ,HttpServletResponse response) {
        captchaService.create(in,response);
    }
}
View Code

Service

@Slf4j
@Service
public class CaptchaService {

    @Autowired
    private RedisService redisService;

    /**
     * @Description: 获取图片验证码
     * @param response:
     * @return: void
     * @author: xx
     * @date: 2021/3/3 4:54 下午
     */
    public void create(ImageVcIn in, HttpServletResponse response) {
        try {
            ValidateCodeProperties validateCodeProperties = new ValidateCodeProperties();
            setHeader(response, validateCodeProperties.getType());
            Captcha captcha = createCaptcha();
            redisService.set("tpyzm-"+in.getImageVcKey(), StringUtils.lowerCase(captcha.text()), validateCodeProperties.getTime());
            captcha.out(response.getOutputStream());
        }catch (IOException e){
            log.error("获取图片验证码失败",e);
        }
    }


    /**
     * @Description: 校验图片验证码是否正确
     * @param key:
     * @param value:
     * @return: void
     * @author: xx
     * @date: 2021/3/3 4:53 下午
     */
    public void check(String key, String value){

        Object codeInRedis = redisService.get("tpyzm-"+key);

        Optional.ofNullable(codeInRedis).orElseThrow(()->new BusinessException("验证码已过期"));

        if (!StringUtils.equalsIgnoreCase(value, String.valueOf(codeInRedis))) {
            throw new BusinessException("验证码不正确");
        }
    }

    /**
     * @Description: 创建图片验证码
     * @param :
     * @return: com.wf.captcha.base.Captcha
     * @author: xx
     * @date: 2021/3/3 9:30 上午
     */
    public Captcha createCaptcha() {
        ValidateCodeProperties validateCodeProperties = new ValidateCodeProperties();
        Captcha captcha = null;
        if (StringUtils.equalsIgnoreCase(validateCodeProperties.getType(), ImageType.GIF)) {
            captcha = new GifCaptcha(validateCodeProperties.getWidth(), validateCodeProperties.getHeight(), validateCodeProperties.getLength());
        } else {
            captcha = new SpecCaptcha(validateCodeProperties.getWidth(), validateCodeProperties.getHeight(), validateCodeProperties.getLength());
        }
        captcha.setCharType(validateCodeProperties.getCharType());
        return captcha;
    }

    /**
     * @Description: 设置返回头信息
     * @param response:
     * @param type:
     * @return: void
     * @author: xx
     * @date: 2021/3/3 9:30 上午
     */
    private void setHeader(HttpServletResponse response, String type) {
        if (StringUtils.equalsIgnoreCase(type, ImageType.GIF)) {
            response.setContentType(MediaType.IMAGE_GIF_VALUE);
        } else {
            response.setContentType(MediaType.IMAGE_PNG_VALUE);
        }
        response.setHeader(HttpHeaders.PRAGMA, "No-cache");
        response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache");
        response.setDateHeader(HttpHeaders.EXPIRES, 0L);
    }
}
View Code

pom

       <!--图片验证码-->
        <dependency>
            <groupId>com.github.whvcse</groupId>
            <artifactId>easy-captcha</artifactId>
            <version>1.6.2</version>
        </dependency> 

 

效果展示:

 

posted @ 2021-03-04 11:08  姜饼攻城狮  阅读(1937)  评论(0编辑  收藏  举报