Я хочу протестировать свое приложение (Angular) в продакшене. Итак, я перенес все необходимые файлы и успешно запустил приложение Spring-Boot (jar). Angular отправляет запросы на 127.0.0.1:
apiHost: 'http://127.0.0.1:8080/'
Конфигуратор выглядит следующим образом:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@CrossOrigin("*")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource(name = "userService")
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/generate-token", "/signup","/config","/saveConfig/","/get/file/*").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Это дает следующие ошибки:
Failed to load http://127.0.0.1:8080/salesStats: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://yzyzyzyz.com' is therefore not allowed access. The response had HTTP status code 503.
Я делаю что-то неправильно ?
@JBNizet: но приложение Spring находится на том же сервере. Таким образом, приложение Angular должно взаимодействовать с ним внутри. Верно ?
Нет, не так. Файлы angular JS находятся на сервере и загружаются вашим браузером на вашу машину разработки, где выполняется код JavaScript. Итак, когда код, запущенный на вашем компьютере, отправляет запрос на 127.0.0.1, он отправляет запрос на ваш компьютер. Если приложение angular и внутренние службы REST обслуживаются одним и тем же сервером, вам не нужен CORS, и вам не нужно указывать какой-либо протокол, хост или порт. Просто отправьте запросы на /salesStats.
Спасибо за это объяснение, и у вас есть причина. Я обязательно протестирую это как можно скорее.
@JBNizet: Это не сработало, так как выдает ошибку 404 Not Found. Считаю, что номер порта обязательно. У вас есть идея?
@JBNizet: И у меня должно быть общее решение, поскольку мы отправим пакет нашим клиентам, и каждый клиент развернет его на своем сервере ... Большое спасибо за вашу помощь.
Если у вас есть уникальный HTTP-сервер, обслуживающий как остальные службы, так и приложение angular, он должен работать. Если вы этого не сделаете, вам необходимо использовать полный URL-адрес ваших служб REST. Понятия не имею, как вы развернули свое угловое приложение.
@JBNizet: приложение Spring работает на встроенном сервере Tomcat (на порту 8080). Приложение angular работает на сервере Apache. И когда ставлю что-то вроде http://myproductionserver:8080/salesStats у меня отклик.
Итак, если я правильно понимаю, у вас есть два отдельных сервера, один для внешнего интерфейса angular, другой для серверных служб, а код, загруженный с Apache, должен отправлять запросы в Tomcat. В этом случае вам понадобится полный URL-адрес сервера TOmcat. Гораздо лучше было бы настроить Apache в качестве обратного прокси-сервера для сервера Tomcat для всех запросов к внутренним службам: все будет обслуживаться с одного HTTP-сервера, вам не понадобится CORS, и вам не нужно будет открывать сервер Tomcat в Интернет.
@JBNizet: Я думаю, что я выберу решение с полным URL-адресом и попытаюсь разрешить пользователю вводить URL-адрес своего сервера при получении пакета и передавать его в приложение Angular. Второе решение неэффективно, поскольку я не могу сказать клиентам, что нужно сделать такую модификацию сервера. Большое спасибо за такую полезную информацию.
Есть также другое решение - внедрить приложение Angular в приложение Spring, я изучаю это.
Запрос OPTIONS, отправленный браузером (предполетный запрос), возвращается с ответом 503 (служба недоступна). Непонятно, почему вы хотите протестировать свой код в продакшене, но отправляете запросы на 127.0.0.1. 127.0.0.1 - это ваша собственная машина для разработки. Не производство.