- 웹소켓 연결
Authorization header 를 추가하여 웹소켓 초기 연결에 성공
const socket = new SockJS(`http://localhost:8080/ws\`, {
headers: {
Authorization: `Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJya2R0amR3bC01QGhhbm1haWwubmV0IiwiYXV0aCI6IlVTRVIiLCJleHAiOjE3MTU5MjU2NTQsImlhdCI6MTcxMjMyNTY1NH0.YL6N05jfWxrIfV07ko4qc6WtiCtTEC6PhNiL0gqRNz0`, // TODO : 헤더에 토큰 넣어야함
},
})
- 웹소켓 연결 CONNECT 시에만 Authorization header 를 추출 후
SecurityContextHolder.getContext().setAuthentication(authentication); 에 authentication 을 추가하도록 하였음 - 기대 효과 :connection 을 맺은 후에는 SecurityContextHolder에 등록된 authentication 으로 User 정보를 가져오는 것
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
// 연결 요청시 JWT 검증
if (StompCommand.CONNECT.equals(accessor.getCommand()) || StompCommand.SEND.equals(accessor.getCommand())) {
log.info(String.valueOf(accessor.getCommand()));
// Authorization 헤더 추출
List authorization = accessor.getNativeHeader("Authorization");
if (authorization != null && !authorization.isEmpty()) {
String jwt = authorization.get(0).substring(7);
try {
// JWT 토큰 검증
Claims decodedJWT = jwtUtil.getUserInfoFromToken(jwt);
String email = decodedJWT.getSubject();
// 사용자 정보 조회
Member member = memberRepository.findByEmail(email).orElseThrow(() ->
new CustomException(ErrorCode.NOT_EXIST_USER)
);
// 사용자 인증 정보 설정
UserDetailsImpl userDetails = new UserDetailsImpl(member);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (RuntimeException e) {
log.error("JWT Verification Failed: " + e.getMessage());
return null;
} catch (Exception e) {
log.error("An unexpected error occurred: " + e.getMessage());
return null;
}
} else {
// 클라이언트 측 타임아웃 처리
log.error("Authorization header is not found");
return null;
}
}
return message;
}
하지만
userDetails 의 payload value 가 empty 라서 발생한 문제
Unhandled exception from message handler method
org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException: Could not resolve method parameter at index 1 in public void cohttp://m.sparta.moit.domain.chat.controller.ChatController.sendChat(java.lang.Long,com.sparta.moit.global.security.UserDetailsImpl,com.sparta.moit.domain.chat.dto.SendChatRequestDto): 1 error(s): [Error in object 'userDetails': codes []; arguments []; default message [Payload value must not be empty]]
at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:128) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:118) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:147) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:567) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:528) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:93) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:522) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:457) ~[spring-messaging-6.1.5.jar:6.1.5]
at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:152) ~[spring-messaging-6.1.5.jar:6.1.5]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
```
'Spring' 카테고리의 다른 글
[스프링코어-2] AppConfig 를 통한 DIP, OCP 해결, 스프링 전환 (0) | 2024.03.12 |
---|
댓글