Olá, pessoal! Estou enfrentando um problema ao tentar fazer uma requisição de WebSocket no meu projeto Angular. A aplicação Angular está rodando no endereço http://localhost:4200/ e o servidor WebSocket está em http://localhost:8080/. Quando tento estabelecer a conexão, recebo o seguinte
erro:
Access to XMLHttpRequest at 'http://localhost:8080/ws/info?t=1741192064562' from origin 'http://localhost:4200/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Além disso, o seguinte erro é registrado:
GET http://localhost:8080/ws/info?t=1741192064562 net::ERR_FAILED 404 (Not Found)
Código que estou utilizando no backend (Spring Boot)
WebSocketConfig.java (Configuração do WebSocket)
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
@RequiredArgsConstructor
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final String allowedOrigin = "http://localhost:4200";
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws") // Endpoint WebSocket
.setAllowedOrigins(allowedOrigin) // Permite origens específicas
.withSockJS(); // Permite fallback para SockJS
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new WebSocketAuthenticationPrincipalArgumentResolver());
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MediaType.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(new ObjectMapper());
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
}
SecurityConfig.java (Configuração de segurança com CORS)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@SuppressWarnings("unused")
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
SecurityFilter securityFilter;
@SuppressWarnings("removal")
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(HttpMethod.POST, "/auth/login").permitAll()
.requestMatchers(HttpMethod.POST, "/auth/register").permitAll()
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Permite requisições OPTIONS
.requestMatchers("/ws/**").permitAll() // Permite WebSocket
.anyRequest().authenticated()
)
.addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
.cors().and();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
CorsConfig.java (Configuração do CORS)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200") // Apenas Angular pode acessar
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // Métodos permitidos
.allowedHeaders("*") // Permite qualquer cabeçalho
.allowCredentials(true); // Permite envio de cookies/tokens
}
}
Código no frontend (Angular)
WebSocketService.ts (Serviço WebSocket)
import { Injectable } from '@angular/core';
import SockJS from 'sockjs-client';
import { Client, over } from '@stomp/stompjs';
@Injectable({
providedIn: 'root',
})
export class WebSocketService {
private stompClient!: Client;
private socketUrl = 'http://localhost:8080/ws'; // URL do WebSocket backend
disconnect(): void {
if (this.stompClient && this.stompClient.connected) {
this.stompClient.disconnect(() => {
console.log('Desconectado do WebSocket');
});
}
}
// Conectar ao WebSocket
connect(callback: (message: any) => void): void {
const socket = new SockJS(this.socketUrl);
this.stompClient = over(socket);
this.stompClient.connect({'Authorization:' : 'Bearer ' + localStorage.getItem('auth-token')}, () => {
console.log('Conectado ao WebSocket');
// Assina o tópico de atualizações
this.stompClient.subscribe('/topic/updates', (message) => {
callback(JSON.parse(message.body)); // Processa a mensagem recebida
});
});
}
sendMessage(content: string): void {
if (this.stompClient && this.stompClient.connected) {
const chatMessage = { content };
this.stompClient.send('/app/message', {}, JSON.stringify(chatMessage));
}
}
}
WebSocketComponent.ts (Componente Angular para interação com o WebSocket)
import { Component, OnDestroy, OnInit } from '@angular/core';
import { WebSocketService } from '../../core/service/web-socket.service';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-web-socket',
imports: [CommonModule],
templateUrl: './web-socket.component.html',
styleUrl: './web-socket.component.css'
})
export class WebsocketComponent implements OnInit, OnDestroy {
messages: string[] = [];
constructor(private webSocketService: WebSocketService) {}
ngOnInit(): void {
this.webSocketService.connect((message: string) => {
this.messages.push(message);
});
}
sendMessage(): void {
this.webSocketService.sendMessage('Olá, WebSocket!');
}
ngOnDestroy(): void {
this.webSocketService.disconnect();
}
}
Top comments (1)
Invés de usar http://, utilize ws://