• 图形验证码如何解决集群中使用问题


           刚才写了一篇文章关于图形验证码的,感觉没有考虑集群情况。其实集群无非加一个集群缓存 将session换成redis或者memcache。

    今天记录一下 使用 redis做集群图形验证码的相关方案。

    基于文章:

    http://www.cnblogs.com/owenma/p/7375540.html

    添加redis:

    在获取和存储的地方使用的是redis封装好的cacheManager。

    @RequestMapping(value = "/getKaptchaImage", method = RequestMethod.GET)
        public
        ModelAndView getImage(HttpServletRequest request, HttpServletResponse response) throws Exception{
            HttpSession session = request.getSession();
            Cache<String, String> kaptcha = cacheManager.getCache("kaptcha");
            String code = kaptcha.get(Constants.KAPTCHA_SESSION_KEY);
    
            System.out.println("******************验证码是: " + code + "******************");
            Producer captchaProducer = (Producer)SpringContextUtils.getBean("captchaProducer");
            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
            session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
            kaptcha.put(Constants.KAPTCHA_SESSION_KEY, 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();
            }
            return null;
        }
    
        @RequestMapping(value = "/checkKaptchaImage", method = RequestMethod.POST)
        public
        @ResponseBody
        Map<String, String> checkKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception{
            Map<String, String> returnMap = new HashMap<>();
            Cache<String, String> kaptcha = cacheManager.getCache("kaptcha");
            //从session中取出servlet生成的验证码text值
            String kaptchaExpected = kaptcha.get(Constants.KAPTCHA_SESSION_KEY);
            //获取用户页面输入的验证码
            String kaptchaReceived = request.getParameter("kaptcha");
            //校验验证码是否正确
            returnMap.put("code", "100");
            if (kaptchaExpected == null){
                returnMap.put("status", "expire");
                return returnMap;
            }
            if (!kaptchaReceived.equalsIgnoreCase(kaptchaExpected)){
                returnMap.put("status", "false");
                return returnMap;
            }
            returnMap.put("status", "true");
            return returnMap;
        }
    

      

    2. cacheManager代码

    package com.nc.shiro.cache;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    
    import org.apache.shiro.cache.Cache;
    import org.apache.shiro.cache.CacheException;
    import org.apache.shiro.cache.CacheManager;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    
    public class RedisCacheManager implements CacheManager {
    
    	private static final Logger logger = LoggerFactory
    			.getLogger(RedisCacheManager.class);
    
    	@Autowired
    	private JedisConnectionFactory connectionFactory;
    
    	private static  RedisRealOPT redisRealOPT;
    
    	// fast lookup by name map
    	private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
    
    
    	/**
    	 * The Redis key prefix for caches
    	 */
    	private String keyPrefix = "shiro_redis_cache:";
    
    	/**
    	 * Returns the Redis session keys
    	 * prefix.
    	 * @return The prefix
    	 */
    	public String getKeyPrefix() {
    		return keyPrefix;
    	}
    
    	/**
    	 * Sets the Redis sessions key
    	 * prefix.
    	 * @param keyPrefix The prefix
    	 */
    	public void setKeyPrefix(String keyPrefix) {
    		this.keyPrefix = keyPrefix;
    	}
    
    	@Override
    	public <K, V> Cache<K, V>  getCache(String name) throws CacheException {
    		logger.debug("获取名称为: " + name + " 的RedisCache实例");
    
    		Cache c = caches.get(name);
    
    		if (c == null) {
    			redisRealOPT = new RedisRealOPT();
    			redisRealOPT.setJedis(connectionFactory.getShardInfo().createResource());
    			redisRealOPT.setExpire(getTTL(name));
    			keyPrefix = name + ":";
    			// create a new cache instance
    			c = new RedisCache<K, V>(redisRealOPT, keyPrefix);
    
    			// add it to the cache collection
    			caches.put(name, c);
    		}
    //		else {
    //			((RedisCache) c).getCache().setJedis(connectionFactory.getShardInfo().createResource());
    //		}
    
    		return c;
    	}
    
    
    	public JedisConnectionFactory getConnectionFactory() {
    		return connectionFactory;
    	}
    
    	public void setConnectionFactory(JedisConnectionFactory connectionFactory) {
    		this.connectionFactory = connectionFactory;
    	}
    
    	private int getTTL(String name){
    		//获得路径
    		File classPath = new File(this.getClass().getResource("/").getPath());
    		File properties = new File(classPath.getPath() + "/cacheManager.properties");
    		Properties prop = new Properties();
    		try {
    			prop.load(new FileInputStream(properties));
    			String propertyNames = prop.stringPropertyNames().toString();
    			if (propertyNames.contains(name)){
    				String value = prop.getProperty(name).trim();
    				return Integer.parseInt(value);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    
    
    		return 0;
    	}
    
    
    }
    

    如果觉得有疑问或者对你有帮助 欢迎评论。

    作者:森林木马

      如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意 

    转载文章之后必须在 文章页面明显位置给出作者和原文连接否则保留追究法律责任的权利。

  • 相关阅读:
    Grails入门教程(二)
    为脚本语言平反JavaScript篇(2)
    【CEO来信】李开复:创新工场我的新公司
    api测试常用测试点
    04 jmeter线程介绍及脚本编写
    02 改变jmeter工具GUI永久使用中文方法
    Mac配置hosts文件
    03 GUI界面的错误日志查看及清除
    页面存在多个url,使用jmeter进行遍历操作
    2.0数据之独立存储(Isolated Storage)
  • 原文地址:https://www.cnblogs.com/owenma/p/7375652.html
Copyright © 2020-2023  润新知