在开发项目的过程中,用户注册通常需要输入图形验证码进行注册防止用户恶意注册,因此,今天带来一个在前后端分离的环境下,实现一个注册验证码模块,样式如下:
1、在后端中引入Hutool
先引入hutool-all依赖;
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
验证码功能位于cn.hutool.captcha
包中,核心接口为ICaptcha
,此接口定义了以下方法:
createCode
创建验证码,实现类需同时生成随机验证码字符串和验证码图片getCode
获取验证码的文字内容verify
验证验证码是否正确,建议忽略大小写write
将验证码写出到目标流中
我们使用 CircleCaptcha圆圈干扰码,
贴栗子:
2、编写验证码实现服务
编写VaildCodeVO封装类保存验证码, 将生成的验证码存入redis中,返回给前端封装类,其中存储的是redis中的Key和生成的图片,redis配置可以参考这篇在Spring-Boot中使用Redis
**
* 验证码封装类
*/
@Data
public class ValidCodeVO {
/**
* 验证码key
*/
String codeKey;
/**
* 验证码图片
*/
String codeValue;
}
编写ValidCodeService接口
public interface ValidCodeService {
/**
* 生成图片验证码
* @return
*/
ValidCodeVO getValidCode();
}
实现ValidCodeService接口
@Service
@Slf4j
public class ValidCodeServiceImpl implements ValidCodeService {
@Resource
private RedisTemplate<String ,String> redisTemplate;
/**
* 获取验证代码对象
* 该方法用于生成一个圆圈验证码,并将其以Base64编码的图像形式和验证码值存储在Redis中。
* 它返回一个ValidCodeVO对象,其中包含了验证码的键和包含Base64编码图像的值。
*
* @return ValidCodeVO 包含验证码键和Base64编码图像值的对象
*/
public ValidCodeVO getValidCode() {
// 生成一个圆圈验证码,设置其大小为100x50,包含4个字符,干扰元素数量为10
// 生成验证码
CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(100, 50, 4, 10);
// 提取验证码的值
String codeValue = circleCaptcha.getCode();
// 将验证码图像转换为Base64编码
String imageBase64 = circleCaptcha.getImageBase64();
// 生成验证码的键,使用当前时间戳以确保唯一性,并设置过期时间为1分钟
// 存入redis
String key = "user:captcha:"+System.currentTimeMillis();
redisTemplate.opsForValue().set(key, codeValue, 1, TimeUnit.MINUTES);
// 创建ValidCodeVO对象,用于封装验证码的键和包含Base64编码图像的值
// 返回
ValidCodeVO validCodeVo = new ValidCodeVO();
validCodeVo.setCodeKey(key);
// 设置验证码的值,先添加前缀"data:image/png;base64,"以标识其为PNG图像数据
validCodeVo.setCodeValue("data:image/png;base64," + imageBase64);
return validCodeVo;
}
}
3、编写controller层接口返回验证码给前端
/**
* 获取验证码
*
* @return
*/
@PostMapping("/getValidCode")
public BaseResponse<ValidCodeVO> getValidCode() {
return ResultUtils.success(validCodeService.getValidCode());
}
4、前端接收并显示
前端我们使用ant-design-pro为例,在注册界面增加如下函数接收验证码,
const refreshCaptcha = async () => {
try{
const res = await getValidCode();
if (res.code === 0) {
if(res.data?.codeValue && res.data?.codeKey){
setCaptchaSrc(res.data.codeValue);
setCaptchaKey(res.data.codeKey);
}
} else {
message.error('刷新验证码失败,请重试');
}
}catch(error){
message.error('刷新验证码失败,请重试');
}
};
useEffect(()=>{
refreshCaptcha();
},[])
增加如下组件显示和发送验证码
<div style={{ display: 'flex' }}>
<ProFormText
name="captcha"
fieldProps={{
size: 'large',
prefix: <LockOutlined/>,
}}
placeholder={intl.formatMessage({ id: '请输入验证码', defaultMessage: '请输入验证码' })}
rules={[
{
required: true,
message: <FormattedMessage id="请输入验证码" defaultMessage="请输入验证码!"/>,
},
]}
/>
<img src={captchaSrc} onClick={refreshCaptcha} style={{ marginLeft: 18 }}
width="100px"
height="39px" />
</div>
以上我们就完成了注册验证码模块的开发。