基于google插件Kaptcha实现图片验证码功能

Kaptcha是谷歌的一个验证码插件,通过引入maven依赖的jar便可以使用到我们的项目中,当然生成验证码也必然要验证是否正确,我的实现是在生成验证码时把验证码存到redis中,验证时通过key从redis中取出验证码和用户输入的验证码对比是否正确。

maven依赖:

<!--https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->

<dependency>

    <groupId>com.github.penggle</groupId>

    <artifactId>kaptcha</artifactId>

    <version>2.3.2</version>

</dependency>



 

然后将生成验证与验证封装到一个service,

public interface IdentifyService{

 

    /**

     * 获取验证码

     * @return

    */

    String getCode(String key, HttpServletRequest req, HttpServletResponseresp) throws ServletException,IOException;

 

    /**

     * 验证验证码

     * @return

    */

    boolean verifyCode(String key, String code);

 

}



 

实现:

@Service

public class IdentifyServiceImplextends KaptchaServlet implements IdentifyService {

 

    private Logger logger= LogManager.getLogger(IdentifyServiceImpl.class);

 

    @Autowired

    private RedisService redisService;

 

    @Override

    public String getCode(String key,HttpServletRequest req, HttpServletResponse resp) throwsServletException,IOException{

       super.init(initServletConfig(req));

       super.doGet(req,resp);

       String code = (String) req.getSession().getAttribute("KAPTCHA_SESSION_KEY");

       redisService.setObject(key,code);

       logger.info("save code to redis ! key : {}, code : {}",key,code);

       return code;

    }

 

    @Override

    public boolean verifyCode(String key,String code){

       String redisCode = redisService.getObject(key);

       redisService.remove(key);

       if(StringUtils.isBlank(redisCode)){

           return false;

       }

       logger.info("get right code from redis ! key : {}, code : {}",key,redisCode);

       return redisCode.equals(code)?true : false;

    }

 

    private ServletConfiginitServletConfig(HttpServletRequest req){

       ServletConfig servletConfig = new ServletConfig() {

           @Override publicString getServletName() {

              // return req.getSession().getServletContext().getServletContextName();

               return null;

           }

 

           @Override publicServletContext getServletContext() {

                returnreq.getSession().getServletContext();

           }

 

           @Overridepublic StringgetInitParameter(String s) {

                //returnreq.getSession().getServletContext().getInitParameter(s);

               return null;

           }

 

           @Override publicEnumeration<String>getInitParameterNames() {

                returnreq.getSession().getServletContext().getInitParameterNames();

           }

       };

       return servletConfig;

    }

 

}



低版本的Kaptcha有kaptchaProducer的默认实现,直接调用doGet()方法即可,但是高版本为了能让用户自定义验证码的属性,必须先调.init()方法实例化kaptchaProducer,所以需要自己实例化一个servletConfig,再调用.init()方法实例化kaptchProducer

 

redis的封装:

public interface RedisService{

 

   <K,V> void setObject(K key, V value);

 

   <K,V> V getObject(K key);

 

   <K> void remove(K key);

 

   <K> void removeAll(K ... keys);

}



实现:

@Service

public class RedisServiceImplimplements RedisService {

 

    private Logger logger= LogManager.getLogger(RedisServiceImpl.class);

 

    @Autowired

    private RedisTemplate redisTemplate;

 

    @Override

    public <K,V> void setObject(K key, V value){

       redisTemplate.opsForValue().set(key,value);

       logger.info("set to redis success!");

    }

 

    @Override

    public <K,V> V getObject(K key){

        V value = (V)redisTemplate.opsForValue().get(key);

       logger.info("get value from redis result: {}",value);

       return value;

    }

 

    @Override

    public <K> void remove(K key){

       redisTemplate.delete(key);

       logger.info("delete from redis success!");

    }

 

    @Override

    public <K> void removeAll(K ... keys){

       redisTemplate.delete(Arrays.asList(keys));

       logger.info("delete all from redis success!");

    }

}



controller层获取验证码与验证接口:

@RestController

@RequestMapping("/identifyCode")

public class IdentifyCodeController{

 

    private static final String INDENTIFY_CODE ="identify_code_register:%s";

    private Logger logger= LogManager.getLogger(IdentifyCodeController.class);

    @Autowired

    private IdentifyService identifyService;

 

    @Autowired

    private ResponseHolder responseHolder;

 

    @RequestMapping(value = "generate", method = RequestMethod.GET)

    public void generateCode(String mobile,HttpServletRequest req, HttpServletResponse resp){

       try {

           String code = identifyService.getCode(String.format(INDENTIFY_CODE, mobile), req, resp);

           logger.info("get verify code ! mobile : {}, code : {}",mobile,code);

       }catch (Exceptione){

           logger.error("get verify code error! mobile : {}",mobile);

       }

    }

 

    @RequestMapping(value = "verify", method = RequestMethod.POST)

    public void verifyCode(String mobile, String code){

       boolean result= identifyService.verifyCode(String.format(INDENTIFY_CODE, mobile),code);

       if(result){

           logger.info("验证通过 ! mobile : {}, code :{}",mobile,code);

       }else {

           logger.info("验证不通过 ! mobile : {}, code: {}",mobile,code);

           responseHolder.setErrorMsg(ErrorMsg.VERIFY_CODE_ERROR);

       }

    }

   

}

其中的ResponseHolder是对controller返回结果的统一处理。我们此处不论。有兴趣去https://github.com/feixiaobo/exercise这里看一下。值得注意的是,我所采用的是spring-boot的架构,所以redis的实现化与注入是spring-boot自己完成的,和spring的jdbcTemplate一个原理,配置文件中配置好属性,直接注入RedisTemplate即可。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值