Skip to content

Commit a264166

Browse files
committed
Merge branch 'dev'
2 parents dddde2a + 7b555fa commit a264166

File tree

4 files changed

+90
-24
lines changed

4 files changed

+90
-24
lines changed

backend/src/main/java/com/deliveranything/domain/notification/controller/NotificationController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public SseEmitter subscribe(
4646
throw new CustomException(ErrorCode.PROFILE_REQUIRED);
4747
}
4848

49-
SseEmitter emitter = new SseEmitter(0L);
49+
SseEmitter emitter = new SseEmitter(60 * 60 * 1000L);
5050
emitterRepository.save(profileId, deviceId, emitter);
5151

5252
// 연결 종료 시 Emitter 제거

backend/src/main/java/com/deliveranything/global/config/WebSocketConfig.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.deliveranything.global.security.handler.StompErrorHandler;
1616
import lombok.RequiredArgsConstructor;
1717
import lombok.extern.slf4j.Slf4j;
18+
import org.springframework.context.annotation.Bean;
1819
import org.springframework.context.annotation.Configuration;
1920
import org.springframework.messaging.Message;
2021
import org.springframework.messaging.MessageChannel;
@@ -29,13 +30,15 @@
2930
import org.springframework.security.core.Authentication;
3031
import org.springframework.security.core.GrantedAuthority;
3132
import org.springframework.security.core.userdetails.UserDetails;
33+
import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity;
3234
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
3335
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
3436
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
3537

3638
@Slf4j
3739
@Configuration
3840
@EnableWebSocketMessageBroker
41+
@EnableWebSocketSecurity
3942
@RequiredArgsConstructor
4043
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
4144

@@ -155,4 +158,14 @@ private Authentication authenticate(StompHeaderAccessor accessor) {
155158
}
156159
});
157160
}
161+
162+
/**
163+
* Disables CSRF for STOMP messages when using @EnableWebSocketSecurity.
164+
* This bean name is specifically recognized by Spring Security to override the default CSRF ChannelInterceptor.
165+
*/
166+
@Bean
167+
public ChannelInterceptor csrfChannelInterceptor() {
168+
// Returning a no-op ChannelInterceptor effectively disables the CSRF check
169+
return new ChannelInterceptor() {};
170+
}
158171
}

backend/src/main/java/com/deliveranything/global/security/config/WebSocketSecurityConfig.java

Lines changed: 0 additions & 23 deletions
This file was deleted.

backend/test_sse.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import requests
2+
import json
3+
import time
4+
5+
BASE_URL = "https://api.deliver-anything.shop"
6+
LOGIN_ENDPOINT = f"{BASE_URL}/api/v1/auth/login"
7+
SSE_ENDPOINT = f"{BASE_URL}/api/v1/notifications/stream"
8+
9+
# 1. 로그인 정보
10+
11+
password = "password2!"
12+
initial_device_id = "test_device_123"
13+
14+
# 2. 로그인 요청
15+
print("로그인 요청 중...")
16+
login_payload = {
17+
"email": email,
18+
"password": password
19+
}
20+
login_headers = {
21+
"Content-Type": "application/json",
22+
"X-Device-ID": initial_device_id
23+
}
24+
25+
try:
26+
login_response = requests.post(LOGIN_ENDPOINT, json=login_payload, headers=login_headers)
27+
login_response.raise_for_status()
28+
29+
access_token = login_response.headers.get("Authorization")
30+
received_device_id_raw = login_response.headers.get("X-Device-ID")
31+
32+
if not access_token:
33+
print("로그인 응답에서 Authorization 헤더를 찾을 수 없습니다.")
34+
print(f"응답 헤더: {login_response.headers}")
35+
print(f"응답 본문: {login_response.text}")
36+
exit()
37+
38+
final_device_id = initial_device_id
39+
if received_device_id_raw:
40+
final_device_id = received_device_id_raw.split(',')[0].strip()
41+
print(f"로그인 응답에서 X-Device-ID를 추출했습니다: {final_device_id}")
42+
else:
43+
print("로그인 응답에서 X-Device-ID 헤더를 찾을 수 없습니다. 초기 device_id를 사용합니다.")
44+
45+
print("로그인 성공!")
46+
print(f"Access Token: {access_token}")
47+
print(f"Final X-Device-ID: {final_device_id}")
48+
49+
# 3. SSE 연결
50+
print("\nSSE 연결 시도 중...")
51+
sse_headers = {
52+
"Accept": "text/event-stream",
53+
"Authorization": access_token,
54+
"X-Device-ID": final_device_id
55+
}
56+
57+
with requests.get(SSE_ENDPOINT, headers=sse_headers, stream=True) as sse_response:
58+
sse_response.raise_for_status()
59+
60+
print("SSE 연결 성공! 이벤트를 수신 중...")
61+
for line in sse_response.iter_lines():
62+
if line:
63+
decoded_line = line.decode('utf-8')
64+
print(decoded_line)
65+
if not line and sse_response.raw.closed:
66+
print("SSE 연결이 종료되었습니다.")
67+
break
68+
time.sleep(0.1)
69+
70+
except requests.exceptions.RequestException as e:
71+
print(f"요청 중 오류 발생: {e}")
72+
if hasattr(e, 'response') and e.response is not None:
73+
print(f"응답 상태 코드: {e.response.status_code}")
74+
print(f"응답 본문: {e.response.text}")
75+
except Exception as e:
76+
print(f"예상치 못한 오류 발생: {e}")

0 commit comments

Comments
 (0)