Avant-propos :
Un projet récent a mené un test d'intrusion, et le résultat exige que le code de vérification sur l'interface de connexion ait une fonction d'utilisation et d'expiration unique.
Pour les petits projets, il n'est pas nécessaire d'utiliser redis pour un code de vérification, donc l'idée originale était de stocker le code de vérification dans la session, mais les extrémités avant et arrière sont séparées, et le projet a un réseau interne et externe, qui entraînera une incohérence de l'identifiant de session dans la même session, de sorte que le code de vérification généré est stocké localement pour être utilisé
Table des matières
1. Obtenez l'image du code de vérification et stockez la valeur du code de vérification
code:
1. Obtenez l'image du code de vérification et stockez la valeur du code de vérification
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. Vérifiez le code de vérification
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. Ajoutez une classe d'outils pour supprimer le code de vérification stocké lors de l'obtention du code de vérification et de la connexion.
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);
}
}