【问题标题】:CORS policy when deleting an item删除项目时的 CORS 策略
【发布时间】:2019-10-14 04:26:17
【问题描述】:

error message in google chrome当我尝试删除一个项目时,我收到了一个错误。

当我向后端添加 Spring Security 时,我遇到了 csrf 的问题,并且无法在 Angular 中显示来自数据库的数据。所以,我做了一些步骤: 我已将@WebSecurityConfigurerAdapter 添加到我的后端。后来在Angular中设置了Interceptor,之后我就可以在后台使用spring security加载我的数据了。

@EnableWebSecurity
@Configuration
public class SpringSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS,"/**").permitAll()
                .anyRequest().authenticated()
                .and()
                //.formLogin().and()
                .httpBasic();
    }
}

我使用 Interceptor 的 Angular 部分服务

import { Injectable } from '@angular/core';
import {HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  intercept(request: HttpRequest<any>, next: HttpHandler) {
    const username = 'damian';
    const password = 'damian';
    const basicAutHeaderString = 'Basic ' + window.btoa(username + ':' + password);



    request = request.clone(
      {
        setHeaders: {
          Authorization: basicAutHeaderString
        }
      }
    );
    return next.handle(request);
  }


  constructor() { }


}

从后端获取单个项目:

  deleteSingleTodo(id) {
    return this.http.delete<Todo>(`http://localhost:8081/${id}`);
  }

我的删除方法是由(点击)按钮触发的:

  deleteTodo(id) {
    console.log(`delete todo ${id}` )
    this.getDataService.deleteSingleTodo( id).subscribe (
      response => {
        console.log(response);
        this.message = `Delete of Todo ${id} Successful!`;
        this.refreshTodos();
      }
    );
  }

I also provided HTTP_INTERCEPTORS in app.module.ts
 providers: [
    { provide: HTTP_INTERCEPTORS, `useClass: HttpInterceptorService, multi:` true}

],[my error message in google][1]

【问题讨论】:

  • 永远不要将错误消息添加为图像。您在哪里配置 CORS 标头?
  • 好的,谢谢你的建议。我在设置拦截器之前得到了标题,现在当我使用拦截器时,它应该在整个应用程序中可见,但只有从数据库中获取所有项目才有效。我是这个全栈世界的初学者。

标签: angular spring-boot cors


【解决方案1】:

您只需将以下类添加为 CORS 配置

它是如何工作的?

CORS 请求会自动分派给已注册的各种 HandlerMapping。它们处理 CORS 预检请求并通过 CorsProcessor 实现(默认为 DefaultCorsProcessor)拦截 CORS 简单和实际请求,以添加相关的 CORS 响应标头(例如 Access-Control-Allow-Origin)。

CorsConfiguration 允许指定如何处理 CORS 请求:允许的来源、标头和方法等。这可以通过多种方式提供

CORS DocCORS with Spring Boot

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
      HttpServletResponse response = (HttpServletResponse) res;
      HttpServletRequest request = (HttpServletRequest) req;
      System.out.println("WebConfig; "+request.getRequestURI());
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
      response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
      response.setHeader("Access-Control-Max-Age", "3600");
      response.setHeader("Access-Control-Allow-Credentials", "true");
      response.setHeader("Access-Control-Expose-Headers", "Authorization");
      response.addHeader("Access-Control-Expose-Headers", "responseType");
      response.addHeader("Access-Control-Expose-Headers", "observe");
      System.out.println("Request Method: "+request.getMethod());
      if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
          try {
              chain.doFilter(req, res);
          } catch(Exception e) {
              e.printStackTrace();
          }
      } else {
          System.out.println("Pre-flight");
          response.setHeader("Access-Control-Allow-Origin", "*");
          response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
          response.setHeader("Access-Control-Max-Age", "3600");
          response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
          "USERID"+"ROLE"+
                  "access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
          response.setStatus(HttpServletResponse.SC_OK);
      }

    }

}

【讨论】:

    【解决方案2】:

    你能简单地添加一个过滤器来应用 CORS,如下所示,看看它是否工作

    @Component
    public class CrossOriginFilter implements Filter {
        private static final Logger log = LoggerFactory.getLogger(CrossOriginFilter.class);
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
            // Called by the web container to indicate to a filter that it is being
            // placed into service.
            // We do not want to do anything here.
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            log.info("Applying CORS filter");
            HttpServletResponse response = (HttpServletResponse) resp;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, Authorization, X-Requested-With, Content-Type, Accept, X-Auth-Token, X-CSRF-TOKEN");
            chain.doFilter(req, resp);
        }
    
        @Override
        public void destroy() {
    
            // Called by the web container to indicate to a filter that it is being
            // taken out of service.
            // We do not want to do anything here.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多