mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-16 12:01:00 +08:00
Compare commits
4 Commits
feature/da
...
feature/da
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61c0336a78 | ||
|
|
0ed9ad2f2a | ||
|
|
67e912381b | ||
|
|
d77baa8a93 |
@@ -92,7 +92,7 @@ public class SecurityConfig {
|
||||
cfg.setAllowedHeaders(List.of("*"));
|
||||
cfg.setAllowCredentials(true);
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", cfg);
|
||||
source.registerCorsConfiguration("/api/**", cfg);
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class SecurityConfig {
|
||||
.exceptionHandling(eh -> eh.accessDeniedHandler(customAccessDeniedHandler))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||
.requestMatchers("/ws/**").permitAll()
|
||||
.requestMatchers("/api/ws/**").permitAll()
|
||||
.requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/posts/**").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/comments/**").permitAll()
|
||||
@@ -173,7 +173,7 @@ public class SecurityConfig {
|
||||
response.getWriter().write("{\"error\": \"Invalid or expired token\"}");
|
||||
return;
|
||||
}
|
||||
} else if (!uri.startsWith("/api/auth") && !publicGet && !uri.startsWith("/ws")) {
|
||||
} else if (!uri.startsWith("/api/auth") && !publicGet && !uri.startsWith("/api/ws")) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.setContentType("application/json");
|
||||
response.getWriter().write("{\"error\": \"Missing token\"}");
|
||||
|
||||
@@ -41,8 +41,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
// Registers the "/ws" endpoint, enabling SockJS fallback options so that alternate transports may be used if WebSocket is not available.
|
||||
registry.addEndpoint("/ws")
|
||||
registry.addEndpoint("/api/ws")
|
||||
// 安全改进:使用具体的允许源,而不是通配符
|
||||
.setAllowedOrigins(
|
||||
"http://127.0.0.1:8080",
|
||||
|
||||
@@ -1,85 +1,83 @@
|
||||
import { ref } from 'vue';
|
||||
import { Client } from '@stomp/stompjs';
|
||||
import SockJS from 'sockjs-client/dist/sockjs.min.js';
|
||||
import { useRuntimeConfig } from '#app';
|
||||
import { ref } from 'vue'
|
||||
import { Client } from '@stomp/stompjs'
|
||||
import SockJS from 'sockjs-client/dist/sockjs.min.js'
|
||||
import { useRuntimeConfig } from '#app'
|
||||
|
||||
const client = ref(null);
|
||||
const isConnected = ref(false);
|
||||
const client = ref(null)
|
||||
const isConnected = ref(false)
|
||||
|
||||
const connect = (token) => {
|
||||
if (isConnected.value) {
|
||||
return;
|
||||
}
|
||||
if (isConnected.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
const API_BASE_URL = config.public.apiBaseUrl;
|
||||
const socketUrl = `${API_BASE_URL}/ws`;
|
||||
const config = useRuntimeConfig()
|
||||
const API_BASE_URL = config.public.apiBaseUrl
|
||||
const socketUrl = `${API_BASE_URL}/api/ws`
|
||||
|
||||
const socket = new SockJS(socketUrl);
|
||||
const stompClient = new Client({
|
||||
webSocketFactory: () => socket,
|
||||
connectHeaders: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
debug: function (str) {
|
||||
},
|
||||
reconnectDelay: 5000,
|
||||
heartbeatIncoming: 4000,
|
||||
heartbeatOutgoing: 4000,
|
||||
});
|
||||
const socket = new SockJS(socketUrl)
|
||||
const stompClient = new Client({
|
||||
webSocketFactory: () => socket,
|
||||
connectHeaders: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
debug: function (str) {},
|
||||
reconnectDelay: 5000,
|
||||
heartbeatIncoming: 4000,
|
||||
heartbeatOutgoing: 4000,
|
||||
})
|
||||
|
||||
stompClient.onConnect = (frame) => {
|
||||
isConnected.value = true;
|
||||
};
|
||||
stompClient.onConnect = (frame) => {
|
||||
isConnected.value = true
|
||||
}
|
||||
|
||||
stompClient.onStompError = (frame) => {
|
||||
console.error('WebSocket STOMP error:', frame);
|
||||
};
|
||||
stompClient.onStompError = (frame) => {
|
||||
console.error('WebSocket STOMP error:', frame)
|
||||
}
|
||||
|
||||
stompClient.activate();
|
||||
client.value = stompClient;
|
||||
};
|
||||
stompClient.activate()
|
||||
client.value = stompClient
|
||||
}
|
||||
|
||||
const disconnect = () => {
|
||||
if (client.value) {
|
||||
isConnected.value = false;
|
||||
client.value.deactivate();
|
||||
client.value = null;
|
||||
}
|
||||
};
|
||||
if (client.value) {
|
||||
isConnected.value = false
|
||||
client.value.deactivate()
|
||||
client.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const subscribe = (destination, callback) => {
|
||||
|
||||
if (!isConnected.value || !client.value || !client.value.connected) {
|
||||
return null;
|
||||
}
|
||||
if (!isConnected.value || !client.value || !client.value.connected) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
const subscription = client.value.subscribe(destination, (message) => {
|
||||
try {
|
||||
if (destination.includes('/queue/unread-count')) {
|
||||
callback(message);
|
||||
} else {
|
||||
const parsedMessage = JSON.parse(message.body);
|
||||
callback(parsedMessage);
|
||||
}
|
||||
} catch (error) {
|
||||
callback(message);
|
||||
}
|
||||
});
|
||||
|
||||
return subscription;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
try {
|
||||
const subscription = client.value.subscribe(destination, (message) => {
|
||||
try {
|
||||
if (destination.includes('/queue/unread-count')) {
|
||||
callback(message)
|
||||
} else {
|
||||
const parsedMessage = JSON.parse(message.body)
|
||||
callback(parsedMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
callback(message)
|
||||
}
|
||||
})
|
||||
|
||||
return subscription
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function useWebSocket() {
|
||||
return {
|
||||
client,
|
||||
isConnected,
|
||||
connect,
|
||||
disconnect,
|
||||
subscribe,
|
||||
};
|
||||
}
|
||||
return {
|
||||
client,
|
||||
isConnected,
|
||||
connect,
|
||||
disconnect,
|
||||
subscribe,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,13 @@ watch(isConnected, (newValue) => {
|
||||
subscription = subscribe(`/topic/conversation/${conversationId}`, (message) => {
|
||||
// 避免重复显示当前用户发送的消息
|
||||
if (message.sender.id !== currentUser.value.id) {
|
||||
messages.value.push(message)
|
||||
messages.value.push({
|
||||
...message,
|
||||
src: message.sender.avatar,
|
||||
iconClick: () => {
|
||||
navigateTo(`/users/${message.sender.id}`, { replace: true })
|
||||
},
|
||||
})
|
||||
// 实时收到消息时自动标记为已读
|
||||
markConversationAsRead()
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user