From bd6b518aae61608ddc2d82b43ccc283dc95b9c54 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 11 三月 2026 13:59:33 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/common/auth/MfaLoginTicketManager.java | 73 ++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/zy/common/auth/MfaLoginTicketManager.java b/src/main/java/com/zy/common/auth/MfaLoginTicketManager.java
new file mode 100644
index 0000000..85ae878
--- /dev/null
+++ b/src/main/java/com/zy/common/auth/MfaLoginTicketManager.java
@@ -0,0 +1,73 @@
+package com.zy.common.auth;
+
+import com.core.common.Cools;
+import org.springframework.stereotype.Component;
+
+import java.security.SecureRandom;
+import java.util.Base64;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class MfaLoginTicketManager {
+
+ private static final long EXPIRE_MILLIS = 5 * 60 * 1000L;
+
+ private final SecureRandom secureRandom = new SecureRandom();
+ private final ConcurrentHashMap<String, TicketHolder> holders = new ConcurrentHashMap<>();
+
+ public String create(Long userId) {
+ cleanup();
+ String ticket;
+ do {
+ ticket = randomTicket();
+ } while (holders.putIfAbsent(ticket, new TicketHolder(userId, System.currentTimeMillis() + EXPIRE_MILLIS)) != null);
+ return ticket;
+ }
+
+ public Long getUserId(String ticket) {
+ if (Cools.isEmpty(ticket)) {
+ return null;
+ }
+ TicketHolder holder = holders.get(ticket);
+ if (holder == null) {
+ return null;
+ }
+ if (holder.expireAt < System.currentTimeMillis()) {
+ holders.remove(ticket);
+ return null;
+ }
+ return holder.userId;
+ }
+
+ public void remove(String ticket) {
+ if (!Cools.isEmpty(ticket)) {
+ holders.remove(ticket);
+ }
+ }
+
+ private void cleanup() {
+ long now = System.currentTimeMillis();
+ for (Map.Entry<String, TicketHolder> entry : holders.entrySet()) {
+ if (entry.getValue().expireAt < now) {
+ holders.remove(entry.getKey());
+ }
+ }
+ }
+
+ private String randomTicket() {
+ byte[] bytes = new byte[24];
+ secureRandom.nextBytes(bytes);
+ return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
+ }
+
+ private static final class TicketHolder {
+ private final Long userId;
+ private final long expireAt;
+
+ private TicketHolder(Long userId, long expireAt) {
+ this.userId = userId;
+ this.expireAt = expireAt;
+ }
+ }
+}
--
Gitblit v1.9.1