代码改变世界

easylive-注册 - 详解

2025-10-14 09:52  tlnshuju  阅读(7)  评论(0)    收藏  举报

1.图片验证码

1.生成算数图片验证码

为了防止恶意注册,使用图像验证码进行校验,如图:

生成图片使用easy-captcha,这是github上的开源项目,使用maven导入:

            
                com.github.whvcse
                easy-captcha
                1.6.2
            

使用里面的算数验证码,并获取结果

        //		生成算数验证码,规定大小
		ArithmeticCaptcha captcha = new ArithmeticCaptcha(100, 42);
        //		获取答案
		String code = captcha.text();

在将图片转换为base64编码形式,base64是将图片等装换为文本格式的编码形式,返回前端直接生成图片

//		将图片转装换为base64编码,返回给前端
		String checkCodeBase64 = captcha.toBase64();

2.使用token存储答案

对于存储答案只需要生成一个唯一的key进行存储,为了方便管理,使用统一的前缀加上全局唯一的值,前缀是常量,添加到一个类中进行管理,其中包括其他常量

public class Constants {
    public static final String USER_PASSWORD_RULER="^(?=.*[0-9])(?=.*[a-zA-Z])[0-9A-Za-z]{6,18}$";
    public static final int USER_ID_LENGTH=10;
    public static final String REDIS_KEY_PREFIX="easylive:";
    public static final String REDIS_KEY_CHECK_CODE=REDIS_KEY_PREFIX+"checkcode:";
    public static final Integer REDIS_KEY_EXPIRE_TIME_ONE_MIN=1000*60;
}

对于全局唯一的值,使用uuid进行生成,并将其转换为字符串,与REDIS_KEY_CHECK_CODE进行拼接,作为key,生成的答案作为Value进行先存储,有效期设置为10分钟

//        存入数据
redisUtils.setex(Constants.REDIS_KEY_CHECK_CODE+ checkCodeKey,code,Constants.REDIS_KEY_EXPIRE_TIME_ONE_MIN*10);

3.返回数据

最后进行数据封装并返回给前端

//		构造返回值
		Map result = new HashMap<>();
		result.put("checkCode", checkCodeBase64);
		result.put("checkCodeKey", checkCodeKey);

2.注册

1.参数校验

对于传递的参数,前端会进行一次校验,但直接调用可以跳过前端校验,所以在后端接受参数时,也要进行一次校验

@NotEmpty @Email @Size(max=150) String email
,@NotEmpty @Size(max=20) String nickName
,@NotEmpty @Pattern(regexp = Constants.USER_PASSWORD_RULER) String registerPassword
,@NotEmpty String checkCodeKey,@NotEmpty String checkCode

使用注解进行校验,需要在该方法的类加上@Validated注解,可以使用:

  • NotEmpty  判断非空
  • Email 是否符合邮箱形式
  • Size 限制大小
  • Pattern 使用正则表达式进行校验

2.验证码答案校验

对于一个验证码,在使用之后一定要进行销毁,防止使用穷举,使用try-finally在try中执行逻辑,finally进行销毁验证码

前端传入了key与用户给出的答案,通过key寻找正确答案,与用户的答案进行对比,出错就抛出异常并删除该key

3.添加用户数据进数据库

如果验证码正确,用户就进行加入数据库的操作,在加入时,要保证邮箱与昵称的唯一,在数据库中这两个字段设置为非空,进行兜底,防止代码漏洞

在封装用户信息时,要使用随机用户id,防止规律明显,被轻易猜出

在设置用户状态与性别时,使用枚举类,而不是普通的常量,使用枚举类可以加强可读性,知道代号的具体含义,拥有独立的命名空间,逻辑清晰,它的可扩展性强,可以附加方法,实现单例模式的最佳方法

性别的枚举类:

public enum UserSexEnum {
    WOMAN(0,"女"),
    MAN(1,"男"),
    SECRET(2,"保密");
    private Integer type;
    private String desc;
    UserSexEnum(Integer type, String desc) {
        this.type = type;
        this.desc = desc;
    }
    public static UserSexEnum getDescByType(Integer type) {
        for (UserSexEnum value : UserSexEnum.values()) {
            if (value.getType().equals(type)) {
                return value;
            }
        }
        return null;
    }
    public Integer getType() {
        return type;
    }
    public String getDesc() {
        return desc;
    }
}

封装用户数据后就可以将用户信息保存进入数据库。注册完成