[英]Angular and Spring boot - POST Request become OPTIONS
I'm developing my API using Spring boot (and Spring Security) and the front with Angular.我正在使用 Spring Boot(和 Spring Security)和 Angular 前端开发我的 API。
Thee TypeScript code :你打字稿代码:
return this.http.post<any>('http://localhost:8080/users',
{
firstName: 'Clemi',
lastName: 'Le boss',
mail: 'clemclem'
});
My controller :我的控制器:
@RestController
@RequestMapping(path = "/users")
public class UserController
{
@Autowired
private UserService userService;
...
@PostMapping()
public ResponseEntity<Object> addUser(Principal principal, @RequestBody User user) {
User savedUser = userService.save(user);
return new ResponseEntity<Object>(HttpStatus.OK);
}
}
And the security config :和安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint() {
})
.and()
.authenticationProvider(getProvider())
.formLogin()
.loginProcessingUrl("/login")
.successHandler(new AuthentificationLoginSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new AuthentificationLogoutSuccessHandler())
.invalidateHttpSession(true)
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers(HttpMethod.GET, "/users/**").authenticated()
.antMatchers(HttpMethod.DELETE, "/users/**").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT).hasRole("USER")
.anyRequest().permitAll()
.and()
.httpBasic();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
private class AuthentificationLoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
}
}
private class AuthentificationLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
}
}
@Bean
public AuthenticationProvider getProvider() {
AuthService provider = new AuthService();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(bCryptPasswordEncoder());
return provider;
}
}
When I use postman my request works fine.当我使用邮递员时,我的请求工作正常。 But when I use my front every request are turned into OPTIONS request.
但是当我使用我的前端时,每个请求都变成了 OPTIONS 请求。 I read multiples articles explaining it's because of Cross Origin Request and could be a 'preflight request' but I don't know how to fix it...
我阅读了多篇文章,解释这是因为跨源请求,并且可能是“预检请求”,但我不知道如何解决它...
Any idea ?任何想法 ?
The behavior is due to CORS
.该行为是由于
CORS
。 Their are two approaches to deal with this behavior.他们是处理这种行为的两种方法。
ACCEPT HEADER
on server end.ACCEPT HEADER
。 Indeed this will work but, it is not a good practice to add accept
header on your server code.accept
标头并不是一个好习惯。PROXY
A very common architecture for any application having service
, frontend
is that they have proxy manager in between like nginx
, apache
. PROXY
对于任何具有service
应用程序来说,这是一个非常常见的架构, frontend
是它们之间有代理管理器,例如nginx
、 apache
。 But again this works for production env
.production env
。 For development purpose angular cli
comes bundled with in-built lite-server
which host the live preview on ng serve
.Here is the needed configuration required to setup proxy on lite server
.angular cli
与内置的lite-server
捆绑在一起,它在ng serve
上托管实时预览。这是在lite server
上设置代理所需的配置。 i.一世。 Create a file call
proxy-config.json
at root of the angular project.在 angular 项目的根目录创建一个文件调用
proxy-config.json
。 ii. ii. Add Following content based on the server address.
根据服务器地址添加以下内容。
{
"/api": {
"target": "http://localhost:8080/",
"changeOrigin": true,
"secure": false,
"pathRewrite": {
'^/api': ''
}
}
}
/api
is the proxy
part of the all the end points from your angular application /api
是 angular 应用程序中所有端点的proxy
部分
http://localhost:8080/accounts(actual server endpoint)
-----> http://localhost:8080/api/accounts(proxy end point)
http://localhost:8080/accounts(actual server endpoint)
-----> http://localhost:8080/api/accounts(proxy end point)
Then modify following script command in package.json
然后在
package.json
修改以下脚本命令
"start": "ng serve --proxy-config proxy.config.json --port 4200",
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.