zoukankan      html  css  js  c++  java
  • 验证码的编写

    1.js的编写

    //更换图片
    function changeImg(){    
        var imgSrc = $("#imgObj");    
        var src = imgSrc.attr("src");    
        imgSrc.attr("src",chgUrl(src));    
    }    
    //时间戳    
    //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳    
    function chgUrl(url){    
        var timestamp = (new Date()).valueOf();    
        if((url.indexOf("&")>=0)){    
            url = url + "×tamp=" + timestamp;    
        }else{    
            url = url + "?timestamp=" + timestamp;    
        }    
        return url;    
    }

    2.生成验证码图片的代码

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    /**
     * Created by funian on 2018/7/12.
     */
    @WebServlet(urlPatterns="/verifyCodeServlet", description="生成验证码")
    public class VerifyCodeServlet extends HttpServlet {
    
        private Logger LOGGER = LoggerFactory.getLogger(VerifyCodeServlet.class);
    
        private static final int WIDTH = 70;// 验证码图片的宽度。
        private static final int HEIGHT = 34;// 验证码图片的高度。
        private static final int CODE_COUNT = 4;// 验证码字符个数
    
        private Random r = new Random();
        // 定义有那些字体   { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" };
        private String[] fontNames = { "华文楷体"};
        // 定义有那些验证码的随机字符
        private String codes = "123456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
        // 用于gettext 方法 获得生成的验证码文本
        private String text = "";
    
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp){
    
            //生成图片
            BufferedImage buffImg = createImage();
    
            // 将四位的验证码保存到Session中
            String validateCode = getText();
            HttpSession session = req.getSession();
            session.setAttribute("validateCode", validateCode);
            // 禁止图像缓存。
            resp.setHeader("Pragma", "no-cache");
            resp.setHeader("Cache-Control", "no-cache");
            resp.setDateHeader("Expires", 0);
            resp.setContentType("image/jpeg");
            // 将图像输出到Servlet输出流中。
            try (ServletOutputStream sos = resp.getOutputStream()){
                ImageIO.write(buffImg, "jpeg", sos);
            } catch (IOException e) {
                LOGGER.error("生成验证码异常", e);
            }
        }
    
        // 得到验证码的文本 后面是用来和用户输入的验证码 检测用
        public String getText() {
            return text;
        }
    
        // 生成随机颜色
        private Color randomColor() {
           // int red = r.nextInt(150);
           // int green = r.nextInt(150);
           // int blue = r.nextInt(150);
            return new Color(44, 47, 250);
        }
    
        // 生成随机字体
        private Font randomFont() {
            int index = r.nextInt(fontNames.length);
            String fontName = fontNames[index];//生成随机的字体名称
            int style = r.nextInt(3);//生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
            int size = r.nextInt(5) + 24;//生成随机字号, 24 ~ 28
            return new Font(fontName, style, size);
        }
    
        // 画干扰线
        private void drawLine(BufferedImage image) {
            int num = 3;//一共画3条
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            for (int i = 0; i < num; i++) {
                int x1 = r.nextInt(WIDTH);
                int y1 = r.nextInt(HEIGHT);
                int x2 = r.nextInt(WIDTH);
                int y2 = r.nextInt(HEIGHT);
                g2.setStroke(new BasicStroke(1.5F));
                g2.setColor(Color.blue);//干扰线是蓝色
                g2.drawLine(x1, y1, x2, y2);
            }
        }
    
        // 得到codes的长度内的随机数 并使用charAt 取得随机数位置上的codes中的字符
        private char randomChar() {
            int index = r.nextInt(codes.length());
            return codes.charAt(index);
        }
    
        // 创建BufferedImage
        private BufferedImage getImage () {
            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = (Graphics2D)image.getGraphics();
            g2.setColor(Color.WHITE);
            g2.fillRect(0, 0, WIDTH, HEIGHT);
            return image;
        }
    
        // 创建一张验证码的图片
        public BufferedImage createImage() {
            BufferedImage image = getImage ();
            Graphics2D g2 = (Graphics2D)image.getGraphics();
            StringBuilder sb = new StringBuilder();
            // 向图中画字符
            for (int i = 0; i < CODE_COUNT; i++) {
                String s = randomChar() + "";
                sb.append(s);
                float x = i * 1.0F * WIDTH / 4;//设置当前字符的x轴坐标
                g2.setFont(randomFont());//设置随机字体
                g2.setColor(randomColor());//设置随机颜色
                g2.drawString(s, x, HEIGHT - 5);//画图
            }
            this.text = sb.toString();
            //添加干扰线
            drawLine(image);
            // 返回图片
            return image;
    
        }
    }

    3.拦截器的验证码代码

    import im.lsn.framework.jpa.JpaRepositoryImpl;
    import im.lsn.framework.shrio.CustomSecurityException;
    import im.lsn.oss.exhibition.entity.QTbUser;
    import im.lsn.oss.exhibition.entity.TbUser;
    import im.lsn.oss.exhibition.entity.enumerate.LoginType;
    import im.lsn.oss.exhibition.service.ClickedCountService;
    import im.lsn.oss.exhibition.service.CustomizedToken;
    import im.lsn.oss.exhibition.service.SecurityService;
    import im.lsn.oss.exhibition.service.UserLoginToken;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
    import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
    import org.apache.shiro.web.util.WebUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import javax.annotation.PostConstruct;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    public class AdminFilter extends FormAuthenticationFilter {
        protected String getCaptcha(ServletRequest request) {
            return WebUtils.getCleanParam(request, "captcha");
        }
    
        public AdminFilter() {
        }
    
        @Autowired
        private SecurityService securityService;
        @Autowired
        private ClickedCountService clickedCountService;
    
        @PersistenceContext
        protected EntityManager entityManager;
        private JpaRepositoryImpl<TbUser, Long> userRepository;
        @PostConstruct
        public void initSecurityService() {
            this.userRepository = new JpaRepositoryImpl<TbUser, Long>(TbUser.class, entityManager);
        }
    
        @Override
        protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
            Subject subject = SecurityUtils.getSubject();
            if (subject != null) {
                UserLoginToken loginToken = (UserLoginToken) subject.getPrincipal();
                if (loginToken != null && loginToken.getType().equalsIgnoreCase(LoginType.FRONT.toString())) {
                    securityService.logout();
                }
            }
            return super.preHandle(request, response);
    
        }
    
        protected CustomizedToken createToken(ServletRequest request, ServletResponse response) {
            String username = this.getUsername(request);
            String password = this.getPassword(request);
            String captcha = this.getCaptcha(request);
            boolean rememberMe = this.isRememberMe(request);
            String host = this.getHost(request);
            String type = LoginType.ADMIN.toString();
            return new CustomizedToken(username, password.toCharArray(), rememberMe, host, captcha, type);
        }
    
        protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
            String failureMessage = this.getFailureKeyAttribute() + ".message";
            if (ae instanceof CustomSecurityException) {
                if(StringUtils.equals("用户名或密码错误",ae.getMessage())){
                    QTbUser qUser = QTbUser.tbUser;
                    TbUser user = userRepository.findOne(qUser.username.eq(((ShiroHttpServletRequest) request).getCookies()[1].getValue()));
                    Integer count = user.getClickedCount();
                    count++;
                    clickedCountService.updateClickedCount(user.getId(),count);
                }
                request.setAttribute(failureMessage, ae.getMessage());
            }
    
            if (ae instanceof UnknownAccountException) {
                request.setAttribute(failureMessage, "用户不存在 ");
            }
    
            if (ae instanceof IncorrectCredentialsException) {
                request.setAttribute(failureMessage, "密码错误");
            }
    
            super.setFailureAttribute(request, ae);
        }
    
        @Override
        protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
            String failureMessage = this.getFailureKeyAttribute() + ".message";
            // 在这里进行验证码的校验
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpSession session = httpServletRequest.getSession();
    
            // 取出验证码
            String validateCode = (String) session.getAttribute("validateCode");
            // 取出页面的验证码
            // 输入的验证和session中的验证进行对比
            String randomcode = httpServletRequest.getParameter("veryCode");
            if (StringUtils.isNotBlank(randomcode)&& StringUtils.isNotBlank(validateCode)&&!randomcode.equalsIgnoreCase(validateCode)){
                request.setAttribute(failureMessage,"验证码错误");
                QTbUser qUser = QTbUser.tbUser;
                TbUser user = userRepository.findOne(qUser.username.eq(((ShiroHttpServletRequest) request).getCookies()[1].getValue()));
                if(null!=user){
                    Integer count = user.getClickedCount();
                    count++;
                    clickedCountService.updateClickedCount(user.getId(),count);
                }
                return true;
            }
            return super.onAccessDenied(request, response);
        }
    
        @Override
        protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
            QTbUser qUser = QTbUser.tbUser;
            TbUser user = userRepository.findOne(qUser.username.eq(((ShiroHttpServletRequest) request).getCookies()[1].getValue()));
            clickedCountService.updateClickedCount(user.getId(),0);
            WebUtils.issueRedirect(request, response, this.getSuccessUrl(), null, true);
        }
    }

    4.前端的验证码

    <div class="row">
                    <div class="col-xs-9">
                        <div class="form-group has-feedback">
                            <input id="veryCode" name="veryCode" maxlength="4" class="form-control codeVal" type="text" placeholder="验证码" required />
                            <span class="glyphicon glyphicon-option-horizontal form-control-feedback"></span>
                        </div>
                    </div>
                    <div class="col-xs-3">
                        <img id="imgObj"  align="right" alt="" onclick="changeImg()" src="${ctxRoot}/verifyCodeServlet"/>
                    </div>
                </div>

    5.前端的验证码的js格式验证

    // 验证码校验
        jQuery.validator.addMethod("codeVal", function(value, element) {
            var reg = /^[a-zA-Z0-9]{4}$/;
            return this.optional(element) || (reg.test(value));
        }, "请输入正确的验证码!");
  • 相关阅读:
    Maven项目打包时指定配置策略
    使Jackson和Mybatis支持JSR310标准
    Java 8的Time包常用API
    MySQL 聚集拼接
    将List<E>内对象按照某个字段排序
    判断List<E>内是否有重复对象
    eclipse中Maven项目启动报错“3 字节的 UTF-8 序列的字节 3 无效。”
    控制层@Value注解取不到值
    IntelliJ IDEA实时代码模板
    OD: Exploit Me
  • 原文地址:https://www.cnblogs.com/ly-lyq/p/9965061.html
Copyright © 2011-2022 走看看