Springboot实现验证码登录
Springboot实现验证码登录
1.背景
本人近期正在完成毕业设计(旅游信息管理系统)的制作,采用的SpringBoot+Thymeleaf的模式。在登录网站时想要添加验证码验证,通过网上查找资料,决定整合Kaptcha来实现验证码登录
2.过程
后端代码
2.1 在pom.xml中导入Kaptcha和ajax依赖
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cljs-ajax/cljs-ajax -->
<dependency>
<groupId>cljs-ajax</groupId>
<artifactId>cljs-ajax</artifactId>
<version>0.8.1</version>
</dependency>
这里我用的是Maven项目,非Maven的可以下载相关的jar包;
2.2 新建kaptchaConfig类,配置kaptcha
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 边框颜色
properties.setProperty("kaptcha.border.color", "black");
//边框厚度
properties.setProperty("kaptcha.border.thickness", "1");
// 图片宽
properties.setProperty("kaptcha.image.width", "200");
// 图片高
properties.setProperty("kaptcha.image.height", "50");
//图片实现类
properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
//文本实现类
properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
//文本集合,验证码值从此集合中获取
properties.setProperty("kaptcha.textproducer.char.string", "01234567890");
//验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
//字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体");
//字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
//文字间隔
properties.setProperty("kaptcha.textproducer.char.space", "3");
//干扰实现类
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
//干扰颜色
properties.setProperty("kaptcha.noise.color", "blue");
//干扰图片样式
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
//背景实现类
properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
//背景颜色渐变,结束颜色
properties.setProperty("kaptcha.background.clear.to", "white");
//文字渲染器
properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
2.3 新建CommonUtil工具类
public class CommonUtil {
/**
* 生成验证码图片
* @param request 设置session
* @param response 转成图片
* @param captchaProducer 生成图片方法类
* @param validateSessionKey session名称
* @throws Exception
*/
public static void validateCode(HttpServletRequest request, HttpServletResponse response, DefaultKaptcha captchaProducer, String validateSessionKey) throws Exception{
// Set to expire far in the past.
response.setDateHeader("Expires", 0);
// Set standard HTTP/1.1 no-cache headers.
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
// Set standard HTTP/1.0 no-cache header.
response.setHeader("Pragma", "no-cache");
// return a jpeg
response.setContentType("image/jpeg");
// create the text for the image
String capText = captchaProducer.createText();
// store the text in the session
request.getSession().setAttribute(validateSessionKey, capText);
// create the image with the text
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
// write the data out
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
}
2.4 编写控制层代码,新建MainController类
@Controller
public class MainController {
@Resource
private DefaultKaptcha captchaProducer;
@RequestMapping(value = {"/"})
public String index() {
return "/index";
}
/**
* 登录验证码SessionKey
*/
public static final String LOGIN_VALIDATE_CODE = "login_validate_code";
/**
* 登录验证码图片
*/
@RequestMapping(value = {"/loginValidateCode"})
public void loginValidateCode(HttpServletRequest request, HttpServletResponse response) throws Exception{
CommonUtil.validateCode(request,response,captchaProducer,LOGIN_VALIDATE_CODE);
}
/**
* 检查验证码是否正确
*/
@RequestMapping("/checkLoginValidateCode")
@ResponseBody
public HashMap checkLoginValidateCode(HttpServletRequest request, @RequestParam("validateCode")String validateCode) {
String loginValidateCode = request.getSession().getAttribute(LOGIN_VALIDATE_CODE).toString();
HashMap<String,Object> map = new HashMap<String,Object>();
if(loginValidateCode == null){
map.put("status",null);//验证码过期
}else if(loginValidateCode.equals(validateCode)){
map.put("status",true);//验证码正确
}else if(!loginValidateCode.equals(validateCode)){
map.put("status",false);//验证码不正确
}
map.put("code",200);
return map;
}
}
前端代码
到这里后端的部分已经完成了,大部分都是一样的,只需要轻微改动
2.5 登录界面
这里直接将我网站的登录界面直接贴出,不需要的代码可自行删除。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>会员中心-登录</title>
</head>
<body>
<table class="login_tab" width="270" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>验证码:</td>
<td><input type="text" id="validateCode" name="validateCode" value="" placeholder="请输入验证码"/></td><td> </td>
<td><img id="loginValidateCode" height="35" width="80" style="cursor: pointer;" src="/loginValidateCode" onclick="uploadLoginValidateCode();"></td>
</tr>
<tr>
<td></td>
<td>
<button class="log_b" type="submit">登 录</button>
</td>
</tr>
</table>
<script type="text/javascript" src="/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/js/kaptcha.js"></script>//导入kaptcha.js文件
<script type='text/javascript'></script>
</body>
</html>
2.6 编写js代码,新建kaptcha.js
$(function () {
$("#validateCode").keyup(function(){
checkLoginValidateCode($(this).val());
});
});
function uploadLoginValidateCode() {
//点击验证码刷新验证码
$("#loginValidateCode").attr("src","/loginValidateCode?random="+new Date().getMilliseconds());
}
function checkLoginValidateCode(validateCode) {
var error = $("#validateCode").parent().next();
if(validateCode != null && validateCode != ""){
$.ajax({
type: "POST",
async:false,
url: "/checkLoginValidateCode?validateCode="+validateCode,
success : function(json) {
if(json != null && json.code == 200 && json.status != null) {
if (json.status == true) {
error.html("恭喜你验证码,正确!!!");
} else if(json.status == false){
error.html("验证码错误,请重新输入");
}else{
error.html("验证码过期,请重新输入");
uploadLoginValidateCode();
}
}
return false;
},
error:function(XMLHttpRequest,textStatus,errorThrown){
alert("服务器错误!状态码:"+XMLHttpRequest.status);
// 状态
console.log(XMLHttpRequest.readyState);
// 错误信息
console.log(textStatus);
return false;
}
});
}else{
error.html("请输入验证码!");
}
}
2.7效果图

Springboot实现验证码登录的更多相关文章
- SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能
在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...
- SpringBoot 整合 Shiro 密码登录与邮件验证码登录(多 Realm 认证)
导入依赖(pom.xml) <!--整合Shiro安全框架--> <dependency> <groupId>org.apache.shiro</group ...
- springboot +spring security4 自定义手机号码+短信验证码登录
spring security 默认登录方式都是用户名+密码登录,项目中使用手机+ 短信验证码登录, 没办法,只能实现修改: 需要修改的地方: 1 .自定义 AuthenticationProvide ...
- Springboot 生成验证码
技术:springboot+kaptcha+session 概述 场景介绍 验证码,用于web网站.用户点击验证码图片后,生成验证码.提交后,用户输入验证码和Session验证码,进行校验. 详细 ...
- Spring Security实现短信验证码登录
Spring Security默认的一个实现是使用用户名密码登录,当初我们在开始做项目时,也是先使用这种登录方式,并没有多考虑其他的登录方式.而后面需求越来越多,我们需要支持短信验证码登录了,这时候再 ...
- requests库使用:通过cookie跳过验证码登录,并用Session跨请求保持cookie
拿我平时测试的一个系统为例,从UI层面来说必须先登录才可以进行后续操作,但是我在测试接口文档提供的接口时,发现并不需要登录,每个接口只要传参就可以正常返回.原因是我们这边专门弄了一个接口包来统一管理常 ...
- vue实现短信验证码登录
无论是移动端还是pc端登录或者注册界面都会见到手机验证码登录这个功能,输入手机号,得到验证码,最后先服务器发送请求,保存登录的信息,一个必不可少的功能 思路 1,先判断手机号和验证是否为空, 2,点击 ...
- Spring Security构建Rest服务-1203-Spring Security OAuth开发APP认证框架之短信验证码登录
浏览器模式下验证码存储策略 浏览器模式下,生成的短信验证码或者图形验证码是存在session里的,用户接收到验证码后携带过来做校验. APP模式下验证码存储策略 在app场景下里是没有cookie信息 ...
- Spring Security构建Rest服务-0702-短信验证码登录
先来看下 Spring Security密码登录大概流程,模拟这个流程,开发短信登录流程 1,密码登录请求发送给过滤器 UsernamePasswordAuthenticationFilter 2,过 ...
随机推荐
- C#基础_类与对象的关系
类不占内存,对象占内存
- n【c#】委托:delegate 学习笔记
类似于c/c++的指针,只不过c#的委托存储的是某个方法的调用,派生子System.Delegate
- Sentinel控制台1.8.3修改源码,修改配置后推送到Nacos
目录 1. 接着上一篇 2. 思路 3. 下载Sentinel源码 4. 看Gateway里面读取的配置信息 5. 修改Sentinel控制台源码 6. 熔断规则测试 7. 限流规则测试 8. 打包使 ...
- 华为云计算灾备产品BCManager 及eBackup的组网方式
BCManager的作用 OceanStor BCManager是面向企业数据中心存储容灾业务的管理软件,实现容灾.双活.两地三中心等容灾环境的管理,具备多种数据库应用与虚拟化环境的容灾管理功能,简单 ...
- 全能成熟稳定开源分布式存储Ceph破冰之旅-上
@ 目录 概述 定义 传统存储方式及问题 优势 生产遇到问题 架构 总体架构 组成部分 CRUSH算法 数据读写过程 CLUSTER MAP 部署 部署建议 部署版本 部署方式 Cephadm部署 前 ...
- python 基于aiohttp的异步爬虫实战
钢铁知识库,一个学习python爬虫.数据分析的知识库.人生苦短,快用python. 之前我们使用requests库爬取某个站点的时候,每发出一个请求,程序必须等待网站返回响应才能接着运行,而在整个爬 ...
- Linux使用密钥登录SSH
输入命令和上传密钥时需要注意当前目录.账号和读写权限 生成密钥 使用服务器生成(方法一,推荐) 1.1生成密钥 #ssh-keygen(这里pwd为当前账号的home目录) 1.2下载密钥 .id_r ...
- 修复 Elasticsearch 集群的常见错误和问题
文章转载自:https://mp.weixin.qq.com/s/8nWV5b8bJyTLqSv62JdcAw 第一篇:Elasticsearch 磁盘使用率超过警戒水位线 从磁盘常见错误说下去 当客 ...
- Elasticsearch:Elasticsearch中的refresh和flush操作指南
在今天的文章里,我们来主要介绍一下Elasticsearch的refresh及flush两种操作的区别.如果我们从字面的意思上讲,好像都是刷新的意思.但是在Elasticsearch中,这两种操作是有 ...
- 9. Fluentd部署:日志
Fluentd是用来处理其他系统产生的日志的,它本身也会产生一些运行时日志.Fluentd包含两个日志层:全局日志和插件级日志.每个层次的日志都可以进行单独配置. 日志级别 Fluentd的日志包含6 ...