分为前后端两个部分,先从后端开始:

一、后端

1.1 实体类

首先要创建实体类,要包含验证码的key(我们需要用Key去获取存储在redis中对应的验证码的值)

@Data

public class User {

private int id;

private String username;

private String password;

private String codekey;

private String codevalue;

private String email;

private String role;

private boolean state;

public User() {

}

}

这里遇到过一个很有趣的小BUG,就是不要设置变量为CodeKey这样的大驼峰,或者说,变量的第一个字母一定不要大写,因为可能会导致@Data中的方法无法识别你的变量。

1.2 创建发送给前端验证码信息的controller

前端加载登录页面的时候,需要发送请求给后端,来获取验证码的信息,包括验证码图片的url,以及验证码的key。

@RestController

public class VerificationCodeController {

@Value("${imagepath}")

private String imagepath; // 验证码的本地路径

@Resource

private RedisTemplate redisTemplate; // 将存储验证码的 key - uuid

@RequestMapping("/getcaptcha")

public Object getCaptcha1(){

// 1.生成验证码到本地

// 定义图形验证码的长和宽 (这个验证码的大小需要和自己前端的验证码的大小匹配)

LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(128, 50);

String uuid = UUID.randomUUID().toString().replace("-","");

// 图形验证码写出,可以写出到文件,也可以写出到流

lineCaptcha.write(imagepath + uuid + ".png");

// 验证码的网络地址

String url = "/image/"+uuid+".png";

// 将验证码存储到 redis

redisTemplate.opsForValue().set(uuid,lineCaptcha.getCode());

HashMap res = new HashMap<>();

res.put("code",200);

res.put("codeurl",url);

res.put("codekey",uuid);

String users_json = JSON.toJSONString(res);

return users_json;

}

}

在application.properties文件中,需要配置你的图片存储的位置,加上下面这一行。

imagepath=D:/images/

 1.3 创建处理验证码的controller

接着创建controller,我这里的是登录请求。

@RestController

public class LoginController {

@Autowired

UserDao userDao;

@Resource

private RedisTemplate redisTemplate; // 指定 RedisTemplate 的泛型类型为

@CrossOrigin

@RequestMapping("/login")

public String userLogin(@RequestBody User user) {

// 1.检查验证码是否正确

String redisCodeValue =

(String) redisTemplate.opsForValue().get(user.getCodekey());

if(!StringUtils.hasLength(redisCodeValue) ||

!redisCodeValue.equals(user.getCodevalue())) {

// 验证码不正确

return "验证码错误!";

}

//2.再判断登录信息

String str = "error";

int count = userDao.getUserByMassage(user.getUsername(), user.getPassword());

if (count > 0) {

str = "ok";

}

return str;

}

}

二、前端

2.1 前端的输入框和图片结构

验证码

v-model="loginForm.codevalue"

style="width: 100px;"

placeholder="请输入内容"

>

ref="img"

style="width: 128px; height: 50px"

:src="codeImg"

>

2.2 发出获取验证码信息的请求

async loadCode() {

const res = await this.$http.get("getcaptcha");

this.codeImg = "http://127.0.0.1:9000/" + res.data.codeurl;

this.loginForm.codekey = res.data.codekey;

},

 2.3 登录时携带验证码信息

login() {

this.$refs.loginFormRef.validate(async (valid) => {

if (!valid) return;

// 调用get请求

const { data: res } = await this.$http.post("login", this.loginForm);

if (res == "ok") {

window.sessionStorage.setItem("flag", "ok"); // session 放置

this.$message.success("登陆成功!!!");

this.$router.push({ path: "/home" });

} else {

this.$message.error("登录失败!!!");

}

});

},

三、 总结

从逻辑顺序来讲,前端发送获取验证码请求,后端接收到之后,生成验证码图片,返回图片的信息(url,codeKey),前端拿到返回结果之后,可以通过url展示图片。

接着用户输入信息之后,发送登录请求,后端拿到验证码信息(用户输入的值和codeKey)之后,和存储在redis中的数据进行对比校验,相等的情况下,通过。

相关链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。