【问题标题】:Angular and Spring boot - POST Request become OPTIONSAngular 和 Spring 启动 - POST 请求成为 OPTIONS
【发布时间】:2020-04-18 05:31:34
【问题描述】:

我正在使用 Spring boot(和 Spring Security)和 Angular 开发我的 API。

你的 TypeScript 代码:

return this.http.post<any>('http://localhost:8080/users',
        {
            firstName: 'Clemi',
            lastName: 'Le boss',
            mail: 'clemclem'
        });

我的控制器:

@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);
    }

}

以及安全配置:

@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;
    }
}

当我使用邮递员时,我的请求工作正常。但是当我使用我的前端时,每个请求都变成了 OPTIONS 请求。我阅读了多篇文章,解释这是因为 Cross Origin Request 并且可能是“预检请求”,但我不知道如何解决它......

有什么想法吗?

【问题讨论】:

标签: java angular typescript spring-boot spring-security


【解决方案1】:

该行为是由于 CORS 造成的。它们是处理这种行为的两种方法。

  1. ACCEPT HEADER 在服务器端。这确实可行,但在服务器代码中添加 accept 标头不是一个好习惯。
  2. PROXY 对于任何具有service、frontend 的应用程序来说,一个非常常见的架构是它们之间有代理管理器,例如nginx、apache。但这同样适用于production env。出于开发目的,angular cli 与内置的lite-server 捆绑在一起,它在ng serve 上托管实时预览。这是在lite server 上设置代理所需的配置。

我。在 Angular 项目的根目录下创建一个文件调用 proxy-config.json。 ii.根据服务器地址添加关注内容。

{
  "/api": {
    "target": "http://localhost:8080/",
    "changeOrigin": true,
    "secure": false,
    "pathRewrite": {
       '^/api': ''
     }
   }
}

/api 是您的 Angular 应用程序中所有端点的 proxy 部分

http://localhost:8080/accounts(actual server endpoint) -----> http://localhost:8080/api/accounts(proxy end point)

然后在package.json中修改如下脚本命令

"start": "ng serve --proxy-config proxy.config.json --port 4200",

【讨论】:

    【解决方案2】:

    问题是由 CORS 引起的。您需要接受来自另一个域的请求(仅用于本地开发),如图所示here

    【讨论】:

      猜你喜欢
      • 2016-10-10
      • 1970-01-01
      • 2017-01-11
      • 2015-09-01
      • 1970-01-01
      • 2016-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多