跳到主要内容

图片验证码规范

获取验证码API说明

路径

GET: https://{base-api-domain}/captchas/{scene}/{uuid}

参数说明

参数说明
scene场景标识(参考下面表格)
uuid客户端产生的唯一标识

场景标识说明

场景
验证码登录LOGIN
手机注册REGISTER
找回密码FIND_PASSWORD
绑定手机BIND_MOBILE
修改密码MODIFY_PASSWORD
验证手机VALIDATE_MOBILE
添加店员ADD_CLERK
绑定邮箱BIND_EMAIL
设置支付密码SET_PAY_PWD
二次验证TWO_STEP
注销账号LOG_OFF

页面调用示例

在页面可以直接使用HTML的img标签进行展示,如下:

<img src="https://{base-api-domain}/captchas/{scene}/{uuid}">

代码展示

  1. 系统会利用Random随机生成4位有小写英文字母和数字组成的验证码,并利用Graphics将验证码进行画像

  2. 在生成验证码时,系统会将生成的验证码信息存放在Redis缓存中,验证时,直接从缓存中取出验证码进行比对即可

    缓存key格式为:{CAPTCHA}_uuid_scene

  3. 验证码使用时效性的,可在系统的配置文件中进行配置

  4. 生成验证码的业务接口会将验证码信息转换为图片信息并以数据流的形式输出到浏览器端

具体代码如下:

public void writeCode(String uuid, String scene) {
int width = 160, height = 80;

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 获取图形上下文
Graphics g = image.getGraphics();

// 生成随机类
Random random = new Random();

// 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);

// 设定字体
g.setFont(this.getFont());

// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}

String sRand = "";
int car = captchars.length - 1;
//获取站点设置
String siteSettingJson = settingManager.get(SettingGroup.SITE);
//解析站点设置
SiteSetting siteSetting = JsonUtil.jsonToObject(siteSettingJson, SiteSetting.class);
for (int i = 0; i < 4; i++) {
String rand = "" + captchars[generator.nextInt(car) + 1];
if (siteSetting.getTestMode().equals(1)) {
rand = "1";
}
sRand += rand;
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.setColor(new Color(30 + random.nextInt(80), 30 + random.nextInt(80), 30 + random.nextInt(80)));
g.drawString(rand, 30 * i + 20, 58);
}
String key = CachePrefix.CAPTCHA.getPrefix() + uuid + "_" + scene;
String value= sRand.toLowerCase();
cache.put(key, value, javashopConfig.getCaptchaTimout());

// 图象生效
g.dispose();
// 输出图象到页面
HttpServletResponse resp = ThreadContextHolder.getHttpResponse();
//设置头信息为图片类型
resp.setHeader("Pragma", "No-cache");
resp.setHeader("Cache-Control", "no-cache");
resp.setDateHeader("Expires", 0);
resp.setContentType("image/jpeg");
try {
ImageIO.write(image, "JPEG", resp.getOutputStream());
resp.getOutputStream().flush();
resp.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}