Without using redis, the verification code is stored under the condition of separating the front-end and back-end projects

Foreword:

A recent project has conducted a penetration test, and the result requires that the verification code on the login interface must have a one-time use and expire function.

For small projects, there is no need to use redis for a verification code, so the original idea was to store the verification code in the session, but the front and back ends are separated, and the project has an internal and external network, which will cause the sessionid in the same session to be inconsistent, so the generated The verification code is stored locally for use

Table of contents

Foreword:

1. Obtain the verification code picture and store the value of the verification code

Verify the captcha

Add a tool class to delete the stored verification code when obtaining the verification code and logging in


code:

1. Obtain the verification code picture and store the value of the verification code

	public void kaptcha(HttpServletRequest request, HttpServletResponse response) {
		try {
			// 数字类型
			RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
			LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
			lineCaptcha.setGenerator(randomGenerator);
			// 重新生成code
			lineCaptcha.createCode();
			lineCaptcha.write(response.getOutputStream());
			SessionContextUtils sessionContextUtils = SessionContextUtils.getInstance();
			HttpSession session = request.getSession();
			session.removeAttribute("checkCode");
			session.setAttribute("checkCode",lineCaptcha.getCode());
			session.setMaxInactiveInterval(40);
			sessionContextUtils.addSession(session);
			// 关闭流
			response.getOutputStream().close();
		} catch (IOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
	}

2. Verify the verification code

	public boolean check(String kaptcha) {
		if (StringUtils.isEmpty(kaptcha)) {
			return false;
		}
		try {
			SessionContextUtils sessionContextUtils = SessionContextUtils.getInstance();
			return sessionContextUtils.getSession(kaptcha);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

3. Add a tool class to delete the stored verification code when obtaining the verification code and logging in.

package com.xinke.sunshine_ebid.common.utils;
 
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

public class SessionContextUtils {
    
    private static SessionContextUtils instance;
    
    private HashMap<String, Map<String , Object>> sessionMap;
    
    private SessionContextUtils() {
        sessionMap = new HashMap<>();
    }
    
    public static SessionContextUtils getInstance() {
        if (instance == null) {
            instance = new SessionContextUtils();
        }
        return instance;
    }
    
    public synchronized void addSession(HttpSession session) {
        // 30秒删除
        sessionMap.values().removeIf(key -> (Long.parseLong(key.get("expireTime").toString()) + 30 * 1000) <  System.currentTimeMillis());
        if (session != null) {
            Map<String , Object> sessions = new HashMap<>();
            String expireTime = String.valueOf(System.currentTimeMillis());
            sessions.put("expireTime", expireTime);
            sessions.put("session", session);
            String name = (String)session.getAttribute("checkCode");
            if (name != null){
                sessionMap.put(name, sessions);
            }
        }
    }
    
    public synchronized void delSession(HttpSession session) {
        if (session != null) {
            sessionMap.remove(session.getId());
        }
    }

    public synchronized boolean getSession(String sessionName) {
        // 40秒删除
        sessionMap.values().removeIf(key -> (Long.parseLong(key.get("expireTime").toString()) + 60 * 1000) <  System.currentTimeMillis());
        if (sessionName == null) {
            return false;
        }
        Map session  = sessionMap.get(sessionName.toLowerCase());
        if (session != null && session.size() > 0 ){
            sessionMap.remove(sessionName.toLowerCase());
            return true;
        }else {
            return false;
        }
    }
}
package com.xinke.sunshine_ebid.common.utils;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener {
    
    private SessionContextUtils sessionContext= SessionContextUtils.getInstance();
    
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        sessionContext.addSession(session);
    }
    
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        sessionContext.delSession(session);
    }
}

Guess you like

Origin blog.csdn.net/GuaGea/article/details/127440476