Sin usar redis, el código de verificación se almacena bajo la condición de separar los proyectos front-end y back-end

Prefacio:

Un proyecto reciente ha realizado una prueba de penetración y el resultado requiere que el código de verificación en la interfaz de inicio de sesión tenga una función de uso único y caducidad.

Para proyectos pequeños, no es necesario usar redis para un código de verificación, por lo que la idea original es almacenar el código de verificación en la sesión, pero los extremos frontal y posterior están separados, y el proyecto tiene una red interna y externa, que hará que el ID de sesión en la misma sesión sea inconsistente, por lo que el código de verificación generado se almacena localmente para su uso

Tabla de contenido

Prefacio:

1. Obtenga la imagen del código de verificación y almacene el valor del código de verificación

Verifica el captcha

Agregue una clase de herramienta para eliminar el código de verificación almacenado al obtener el código de verificación e iniciar sesión


código:

1. Obtenga la imagen del código de verificación y almacene el valor del código de verificación

	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. Verifica el código de verificación

	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. Agregue una clase de herramienta para eliminar el código de verificación almacenado al obtener el código de verificación e iniciar sesión.

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);
    }
}

Supongo que te gusta

Origin blog.csdn.net/GuaGea/article/details/127440476
Recomendado
Clasificación