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