Skip to content

Commit

Permalink
Merge pull request TeamMajorLink#85 from kchaeeun/refactor#82
Browse files Browse the repository at this point in the history
♻️ [REFACTOR] 토큰 검증을 통해 userId를 받아올 수 있도록 수정
  • Loading branch information
kchaeeun authored Aug 21, 2024
2 parents 94ffa51 + c776f01 commit 098783b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,64 @@
import com.example.majorLink.domain.User;
import com.example.majorLink.dto.response.NotificationResponse;
import com.example.majorLink.global.auth.AuthUser;
import com.example.majorLink.global.jwt.JwtService;
import com.example.majorLink.service.NotificationService;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/notification")
@RequiredArgsConstructor
public class NotificationController {
private final NotificationService notificationService;
private final JwtService jwtService;

/**
* 알림을 위한 구독 API
* [GET] /notification/subscribe
* [GET] /notification/subscribe/{X-AUTH-TOKEN}
* @param lastEventId
* @param userId
* @param token
* @return
*/
// Last-Event-ID는 SSE 연결이 끊어졌을 경우, 클라이언트가 수신한 마지막 데이터 ID 값을 의미, 항상 존재 X -> false
@GetMapping(value = "/subscribe/{X-AUTH-TOKEN}", produces = "text/event-stream")
public SseEmitter subscribe(
@RequestHeader(value = "Last-Event-ID", required = false, defaultValue = "") String lastEventId,
@PathVariable("X-AUTH-TOKEN") String userId) {
return notificationService.subscribe(userId, lastEventId);
@PathVariable("X-AUTH-TOKEN") String token // 경로 변수로 토큰을 받음
) {

// 토큰 유효성 검사
if (!jwtService.checkValidationToken(token)) {
throw new RuntimeException("유효하지 않은 토큰입니다.");
}

// 토큰에서 사용자 UUID 추출
Claims claims = jwtService.getClaims(token);
String userId = claims.get("uuid", String.class);

// UUID 변환 및 검증
UUID userUuid;
try {
userUuid = UUID.fromString(userId);
} catch (IllegalArgumentException e) {
throw new RuntimeException("유효하지 않은 UUID입니다.", e);
}

// notificationService를 통해 사용자 구독 처리
return notificationService.subscribe(userUuid, lastEventId);
}


// 수강 신청 시 튜터에게 알림 전달

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.UUID;

public interface NotificationService {
SseEmitter subscribe(String userId, String lastEventId);
SseEmitter subscribe(UUID userId, String lastEventId);
void send(User sender, Long lectureId, String content);

// 전체 알림 조회
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class NotificationServiceImpl implements NotificationService {
private final LectureRepository lectureRepository;

@Override
public SseEmitter subscribe(String userId, String lastEventId) {
public SseEmitter subscribe(UUID userId, String lastEventId) {
// 토큰을 고유 식별자로 사용하여 emitterId를 생성합니다.
String emitterId = userId + "_" + System.currentTimeMillis();
SseEmitter emitter = emitterRepository.save(emitterId, new SseEmitter(DEFAULT_TIMEOUT));
Expand All @@ -47,7 +47,7 @@ public SseEmitter subscribe(String userId, String lastEventId) {
sendToClient(emitter, emitterId, "EventStream Create. [userId = " + userId + "]");

if (!lastEventId.isEmpty()) {
Map<String, Object> events = emitterRepository.findAllEventCacheStartWithByUserId(UUID.fromString(userId));
Map<String, Object> events = emitterRepository.findAllEventCacheStartWithByUserId(userId);
events.entrySet().stream()
.filter(entry -> lastEventId.compareTo(entry.getKey()) < 0)
.forEach(entry -> sendToClient(emitter, entry.getKey(), entry.getValue()));
Expand Down

0 comments on commit 098783b

Please sign in to comment.