在一些类似于管理系统的项目中,我们在登录时经常会用到图片验证码。这里把我自己写的一个小系统(后台是java语言)的验证码部分摘出来。
总体思路是后端有一个生成验证码图片的接口,把验证码图片写入浏览器,前端页面在img标签里的src属性里填写后端生成验证码图片的接口地址即可。
1、java部分-CaptchaController.java
我这里是把后端生成的验证码生成图片返回给浏览器时,同时存入到了数据库中,前端登录时,后端根据前端输入的验证码和数据库中的验证码作对比,来判断是否可以登录。
package com.lin.controller; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.lin.domain.Captcha; import com.lin.service.SysUserService; /** * 验证码-controller * @author libo */ @Controller @RequestMapping("/captcha") public class CaptchaController { @Autowired private SysUserService uService; /** * 随机字符字典 */ private static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u' ,'v', 'w', 'x', 'y', 'z'}; /** * 随机数 */ private static Random random = new Random(); /** * 获取4位随机数 * @return */ private static String getRandomString() { StringBuffer buffer = new StringBuffer(); for(int i = 0; i < 4; i++) { buffer.append(CHARS[random.nextInt(CHARS.length)]); } return buffer.toString(); } /** * 获取随机数颜色 * @return */ private static Color getRandomColor() { return new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255)); } /** * 返回某颜色的反色 * @param c * @return */ private static Color getReverseColor(Color c) { return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue()); } /** * 生成验证码 * @param request * @param response * @throws ServletException * @throws IOException */ @ResponseBody @RequestMapping(value="/getCaptcha.do", method=RequestMethod.GET) public void outputCaptcha(HttpServletRequest request, HttpServletResponse response, String rad) throws ServletException, IOException { // 设置页面不缓存 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); String randomString = getRandomString(); //生成的验证码 Captcha c = new Captcha(); c.setCaptchaId(rad); c.setCaptcha(randomString.toUpperCase()); Integer id = uService.saveCaptcha(c);//保存验证码到数据库中 if(id > 0){ //验证码保存成功 }else{ //验证码保存失败 return; } int width = 100; //验证码图像的宽度 int height = 34; //验证码图像的高度 // 在内存中创建图象 BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); for(int i=0; i<randomString.length(); i++){ Color color = getRandomColor(); Color reverse = getReverseColor(color); g.setColor(color); //设置字体颜色 g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 25)); //设置字体样式 g.fillRect(0, 0, width, height); g.setColor(reverse); g.drawString(randomString, 18, 25); } //随机生成一些点 for (int i = 0, n = random.nextInt(100); i < n; i++) { g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1); } // 随机产生干扰线,使图象中的认证码不易被其它程序探测到 for (int i = 0; i < 10; i++) { g.setColor(getRandomColor()); final int x = random.nextInt(width-1); // 保证画在边框之内 final int y = random.nextInt(height-1); final int xl = random.nextInt(width); final int yl = random.nextInt(height); g.drawLine(x, y, x + xl, y + yl); } g.dispose(); //图像生效 ImageIO.write(bi, "JPEG", response.getOutputStream()); //输出图片到页面 } }
2、html部分-login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>后台管理系统登录</title> <link rel="stylesheet" href="/common/css/index.css"> <script src="/scripts/apiConfig.js"></script> <script src="/lib/jquery/jquery.min.js"></script> <script src="/lib/aes/aes.min.js"></script> <script src="/common/js/utils.js"></script> </head> <body> <div class="layout"> <div class="top-name">后台管理系统 <span>Background Management System</span> </div> <div class="main"> <div class="item"> <label style="word-spacing: 10px;">邮 箱:</label> <input type="text" id="loginEmail" class="f-s-14" autocomplete="off" placeholder="请输入邮箱"> <span class="err-tip" id="tipLEmail" ng-class="m-l-15"></span> </div> <div class="item"> <label style="word-spacing: 10px;">密 码:</label> <input type="password" id="loginPwd" class="f-s-14" autocomplete="off" placeholder="请输入密码"> <span class="err-tip " id="tipLPwd" ng-class="m-l-15"></span> </div> <div class="item clearfix"> <label>验证码:</label> <input type="text" id="captcha" class="f-s-14" placeholder="请输入验证码" style=" 200px;"> <a href="javascript:void(0);" onclick="updateCaptcha()" style="height: 36px; 100px;float: right;"> <img src="" alt="" id="captcha_img"> </a> <span class="err-tip" id="tipCaptcha" ng-class="m-l-15"></span> </div> <div style="text-align: center;margin-top: -10px;height: 20px;margin-bottom: 5px;"> <span class="err-tip" id="error" ng-class="m-l-15" style="font-size: 14px;"></span> </div> <div class="item"> <button type="button" class="submit" id="submit" style="outline: none;">登 录</button> </div> </div> </div> </body> <script> //更新验证码 var random = ''; function updateCaptcha() { random = new Date().getTime()+''+Math.floor(Math.random() * Math.pow(10, 8)); $('#captcha_img').attr('src', hostObj.host+'/captcha/getCaptcha.do?rad='+random); } $(function () { //页面加载的时候就获取验证码 updateCaptcha(); $('#loginEmail').blur(function () { checkLoginEmail(); }); $('#loginPwd').blur(function () { checkLoginPwd(); }); $('#captcha').blur(function () { checkCaptcha(); }); $("#submit").click(function() { var flag1 = checkLoginEmail(); var flag2 = checkLoginPwd(); var flag3 = checkCaptcha(); if(!flag1 || !flag2 || !flag3){ return; } $.ajax({ type:'post', url: hostObj.host+'/sysUser/login.do', dataType:"json", data:{ loginEmail:$("#loginEmail").val(), loginPwd:encrypt($("#loginPwd").val()), captcha: $('#captcha').val(), captchaId: random }, success:function(res) { if(res.success == 1){ var user = { id: res.data.id, email: res.data.email, createTime: res.data.createTime.substring(0,19), lastLoginTime: res.data.lastLoginTime.substring(0,19), status: res.data.status } window.location.href = "main.html"; }else{ $('#error').html(res.error.msg); if(res.error.code == 4000){ $('#captcha').focus(); } } }, error:function(res){ $('#error').html('系统错误!'); } }); }); function checkLoginEmail() { if($.trim($('#loginEmail').val()) == ''){ $('#tipLEmail').html('请输入邮箱'); return false; }else{ $('#tipLEmail').html(''); return true; } } function checkLoginPwd() { if($.trim($('#loginPwd').val()) == ''){ $('#tipLPwd').html('请输入登录密码'); return false; }else{ $('#tipLPwd').html(''); return true; } } function checkCaptcha() { if($.trim($('#captcha').val()) == ''){ $('#tipCaptcha').html('请输入验证码'); return false; }else{ $('#tipCaptcha').html(''); return true; } }</script> </html>
3、效果
需要购买阿里云产品和服务的,点击此链接领取优惠券红包,优惠购买哦,领取后一个月内有效: https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=fp9ccf07