java web 项目验证码的刷新问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java web 项目验证码的刷新问题相关的知识,希望对你有一定的参考价值。
验证码是通过名为"PictureCheckCode"的servlet来生成的图片,当我点超链接“看不清,换一张”时,整个页面刷新了,然后填好的用户名和密码都清空了。怎么才能实现只刷新验证码而不刷新整个页面呢?
你可以用js来更新img的src属性,例如<img src="PicktureCheckCode" id="CreateCheckCode" align="middle" onclick="this.src=this.src+'?'" />
<a href="javascript:CreateCheckCode.onclick()">看不清,换一张</a> 参考技术A 用js换 img的src就行了啊。
function change()
document.getElementById("CreateCheckCode").src="PictureCheckCode?"+Math.random();
</script>
<img id="CreateCheckCode" src="PictureCheckCode" onclick="change()" /> 参考技术B 很简单啊,你用ajax做你的验证码就好了
就可以保证那些不被刷新了,也可以验证码刷新了
程序逸的Java项目之旅-图书管理系统之验证码的校验和遇到的一些问题
今天接着上篇博客>>>>程序逸的Java项目之旅-图书管理系统之验证码和用户数据的后台获取(1),这篇博客中,我们通过一个验证码插件来快速生成了图形验证码,并且我留了一部分坑没有填,所以这篇博客来把这个坑填一下,就是有关这个插件怎么来校验验证码是否和我们在前端输入的验证码一样呢?还有就是有小伙伴给我了我一点博客文章的建议,我会努力加油的。
主要任务
- 【1】:实现Easy-Captcha的后台校验。
- 【2】:实现用户登录的业务处理。
- 【3】:遇到的一些坑和我自己的解决办法。
1.实现Easy-Captcha的后台校验。
- 其实只要通过生成验证码的方法去查看底层源码我们就会发现该工具是生成一个验证码将其保存在session中的,下面请看源码:
- 所以当我们的登录请求进入控制器后,通过一个工具类的方法将你前端输入的验证码和request对象传入进去后,就通过request对象获取当前session中captcha对应的值来进行判断,然后返回一个Boolean类型的值,所以源码部分和使用方法如下:
if (!CaptchaUtil.ver("前端获取的验证码",request)){
CaptchaUtil.clear(request);
}
- 这里的话我将大概的代码部分已经写完了,也就是整体的思路,其实很简单,但
因为我们的项目是前后端分离的项目,所以存在跨域问题,此时我们的请求无法获取到session的值,也就是说上面这种验证方式适合那种前端和后端在一起的整体项目,所以下面我会把这个坑解决。
2.实现用户登录的业务处理。
- 首先我们需要搞清楚一件事,就是登录的话我们需要什么数据,最基本最简单的就是用户名,密码,和验证码,所以我们需要建一个组合类来保存这一组信息,因为我们的实体类Admin里面没有验证码这个属性,我们去pojo包下新建vo包,用来保存我们的组合实体类:
/**
* @author ctvit
* 这里使用了lombok插件,不会的可以去看我之前的博客
*/
@Data
public class AdminVo {
private String adminName;
private String adminPwd;
private String verCode;
}
- OK,前端我们也要去修改一下,有点细节我们没有处理:首先就是验证码的input标签增加name属性:
- 然后就是写js脚本通过ajax来请求接口:这里需要注意的就是通过JSON.stringfy把表单数据转换为json格式,不然数据传输不到后台,还有就是这里的success执行的函数会返回一个r对象,这个就是我们后台返回的数据对象,这里可以看到layui中默认写了一个code,这个就是状态码,我们常见的404,200,500等,所以下一步我们要写一个请求接口返回类,返回接口调用信息和状态码。
/// 登录
var articleFrom = data.field;
$.ajax({
url: 'http://localhost:9000/admin/login',
type: 'POST',
data: JSON.stringify(articleFrom),
contentType : 'application/json',
dateType:"json",
success: function (r) {
if (r.code === 200) {
button.load({
elem: '.login',
time: 1500,
done: function() {
popup.success("登录成功", function() {
location.href = "Pear-Admin-Layui/index.html"
});
}
})
return true;
} else {
layer.msg(r.message);
button.load({
elem: '.login',
time: 1500,
done: function() {
popup.success("登录失败", function() {
location.href = "http://localhost:8080"
});
}
})
return false;
}
}
});
- 新建一个result包,写一个ResultVo类,结构如下:
/**
*
* 接口调用放回结果状态
* * @author ctvit
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVo implements Serializable {
private String message;
private Integer code;
public static ResultVo ok(){
return new ResultVo("",200);
}
public static ResultVo fail(String message){
return new ResultVo(message,500);
}
}
- 这里我就稍微简化了一下,因为状态码很多,但我们就关系访问成功和不成功哈。然后接下来按照我们之前写的,后台已经可以接受到前台输入的数据了,所以我们只要对输入的账号和密码以及验证码进行校验就可以了,具体的流程如下:我们就可以根据这个思路来写代码了。
3.遇到的一些坑和我自己的解决办法。(重头戏)
- 首先就是如果通过easy-captch的那种方式来进行验证码的校验的话,你会发现行不通,因为我debug发现,我们的请求对象中获取的session的值是null,意味这我们永远都是验证码失败,使用这里我们需要使用redis来实现sesionn的共享,这也是一个技术点哈。但幸运的是,springboot集成redsi简单的一批,所以开始填坑了哈。
- 【redis的安装】:你可以安装redsi到linux系统中去,有关教程可以看我这这篇博客
Linux环境下Redis数据库的安装,那我这次是直接安装到win10下了,懒得安装虚拟机了,所以有关win10下的redis安装可以自行百度哈,而且要记得自己的redis密码,最好安装一个redis可视化工具,这样方便我们查看。 - 【springboot集成redis】:
- 到这里我们就可以通过该自动注入的对象调用其方法将验证码存储到redis中去了。实现就是验证码产生的地方,就是我们的CaptchaController,这是我们用来生成验证码的控制器,这里我们对代码进行修改:通过redisTemplate的opsForValue来存储验证码。
/**
* 用于验证密的显示
* @author ctvit
*/
@Controller
public class CaptchaController {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@RequestMapping("/captcha")
public void captcha(HttpServletRequest request,HttpServletResponse response) throws IOException {
CaptchaUtil.out(request,response);
String captcha = (String)request.getSession().getAttribute("captcha");
redisTemplate.opsForValue().set("captcha",captcha);
}
}
- 此时验证码就以及被存储到redis中去了,那我们就可以去AdminController中进行登录的校验了,根据上面的流程图,我们很快就可以实现代码了:这里还有一个坑就是Mybatis-plus的条件查询,这里的话希望大家去网上百度自己学习,这是很锻炼自己能力的,因为你需要去学习使用一个框架技术。
@RestController
@RequestMapping("/admin")
public class AdminController {
@Autowired
private AdminMapper adminMapper;
@Autowired
private RedisTemplate<String,String> redisTemplate;
/**
* 管理员登录
* @CrossOrigin 用于实现跨域请求的问题
*/
@PostMapping("/login")
@CrossOrigin
public ResultVo login(@RequestBody AdminVo adminVo, HttpServletRequest request, HttpServletResponse response){
//1.判断验证码是否正确
String captcha = redisTemplate.opsForValue().get("captcha");
if (!captcha.trim().toLowerCase().equals(adminVo.getVerCode())){
redisTemplate.opsForValue().set("captcha","");
return ResultVo.fail("验证码错误!!!");
}else {
QueryWrapper<Admin> adminQueryWrapper = new QueryWrapper<>();
adminQueryWrapper.eq("ADMIN_NAME", adminVo.getAdminName());
Admin admin = adminMapper.selectOne(adminQueryWrapper);
if (admin == null){
return ResultVo.fail("账号错误!!!");
} else if(!admin.getAdminPwd().equals(adminVo.getAdminPwd())){
return ResultVo.fail("密码错误!!!");
}else {
return ResultVo.ok();
}
}
}
}
4.最终今天完成的效果:
- 实现是确保验证码保存到redis中去了。
- 其次我们输入错误和正确的验证码看是否可以正常的判断:
- 最后我发现还有一个坑,密码框应该不是明文显示的,使用我们修改一下type为password类型。这篇博客来继续造坑吧。
坑(下篇博客填,或者读者自己填):
- 【1】:注册功能的实现。
- 【2】:确保没有登录的情况下不能访问index.html页面,只能访问login.html和register.html注册页面。
- 【3】:注册就有图片上传的功能。
以上是关于java web 项目验证码的刷新问题的主要内容,如果未能解决你的问题,请参考以下文章