现在的web项目基本都是前后端分离的,后台只需要整理数据传给前端进行渲染就行。
验证码也是web中不可缺少的一部分,再以前的前后端不分离的场景中,一般是把图片以io流的方式传给前端,同时把内容存到session中,在前端请求验证的时候就根据request取出验证码的内容进行比对验证。但是前后端分离之后,尤其是跨域之后,每一次请求session将会对应不上,也就无法取出验证码的内容值进行验证啦。
由于前端的<img>标签的src属性支持bese64编码的图片源,所以后台可以将生成的验证码以base64编码形式传给前台进行展示,同时将验证码的内容一起传给前台,考虑到安全性的问题,可以将验证码的内容也经过base64编码,这样每次验证请求的时候就可以对用户输入的验证码进行base64编码之后比对验证。
代码实例:
1.验证码类(包括图片、图片内容)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ImgResult {
String img;
String code;
}
2.生成验证码工具类,这里生成图片的部分是在网上找的,自己生成的是真的丑,把生成的jpg用base64压缩成字符串给
package cn.wzy.util;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
/**
* Created by Wzy
* on 2018/5/11
*/
public class VerifyCodeUtils {
//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
private static Random random = new Random();
/**
* 使用系统默认字符源生成验证码
*
* @param verifySize 验证码长度
* @return
*/
public static String generateVerifyCode(int verifySize) {
return generateVerifyCode(verifySize, VERIFY_CODES);
}
/**
* 使用指定源生成验证码
*
* @param verifySize 验证码长度
* @param sources 验证码字符源
* @return
*/
public static String generateVerifyCode(int verifySize, String sources) {
if (sources == null || sources.length() == 0) {
sources = VERIFY_CODES;
}
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for (int i = 0; i < verifySize; i++) {
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
}