SpringBoot 동시 접속 자 제어 실현 방법
6130 단어 SpringBoot동시 제어로그 인 인원수
demo 기술 선택
만약 에 session 을 사용한다 면 본 고의 사 고 를 참고 할 수 있 습 니 다.다만 코드 에 약간의 변경 이 필요 합 니 다.
두 가지 실현 사고.
타임 스탬프 비교
username:jwtToken 과 같은 key-value 는 Reids 에서 Filter 논 리 는 다음 과 같 습 니 다.
public class CompareKickOutFilter extends KickOutFilter {
@Autowired
private UserService userService;
@Override
public boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response) {
String token = request.getHeader("Authorization");
String username = JWTUtil.getUsername(token);
String userKey = PREFIX + username;
RBucket<String> bucket = redissonClient.getBucket(userKey);
String redisToken = bucket.get();
if (token.equals(redisToken)) {
return true;
} else if (StringUtils.isBlank(redisToken)) {
bucket.set(token);
} else {
Long redisTokenUnixTime = JWTUtil.getClaim(redisToken, "createTime").asLong();
Long tokenUnixTime = JWTUtil.getClaim(token, "createTime").asLong();
// token > redisToken
if (tokenUnixTime.compareTo(redisTokenUnixTime) > 0) {
bucket.set(token);
} else {
// token
userService.logout(token);
sendJsonResponse(response, 4001, " ");
return false;
}
}
return true;
}
}
대열 에서 내차다
public class QueueKickOutFilter extends KickOutFilter {
/**
* /
*/
private boolean kickoutAfter = false;
/**
* 1
*/
private int maxSession = 1;
public void setKickoutAfter(boolean kickoutAfter) {
this.kickoutAfter = kickoutAfter;
}
public void setMaxSession(int maxSession) {
this.maxSession = maxSession;
}
@Override
public boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response) throws Exception {
String token = request.getHeader("Authorization");
UserBO currentSession = CurrentUser.get();
Assert.notNull(currentSession, "currentSession cannot null");
String username = currentSession.getUsername();
String userKey = PREFIX + "deque_" + username;
String lockKey = PREFIX_LOCK + username;
RLock lock = redissonClient.getLock(lockKey);
lock.lock(2, TimeUnit.SECONDS);
try {
RDeque<String> deque = redissonClient.getDeque(userKey);
// token, ;
if (!deque.contains(token) && currentSession.isKickout() == false) {
deque.push(token);
}
// sessionId ,
while (deque.size() > maxSession) {
String kickoutSessionId;
if (kickoutAfter) { //
kickoutSessionId = deque.removeFirst();
} else { //
kickoutSessionId = deque.removeLast();
}
try {
RBucket<UserBO> bucket = redissonClient.getBucket(kickoutSessionId);
UserBO kickoutSession = bucket.get();
if (kickoutSession != null) {
// kickout
kickoutSession.setKickout(true);
bucket.set(kickoutSession);
}
} catch (Exception e) {
}
}
// , ,
if (currentSession.isKickout()) {
//
try {
//
userService.logout(token);
sendJsonResponse(response, 4001, " ");
} catch (Exception e) {
}
return false;
}
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
LOGGER.info(Thread.currentThread().getName() + " unlock");
} else {
LOGGER.info(Thread.currentThread().getName() + " already automatically release lock");
}
}
return true;
}
}
두 가지 방법 을 비교 하 다시범 을 보이다
다운로드 주소:https://gitee.com/yintianwen7/taven-springboot-learning/tree/master/login-control
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.