【问题标题】:How do I allow cross origin request如何允许跨源请求
【发布时间】:2018-04-27 03:33:17
【问题描述】:

我是一名后端开发人员,我正在为从本地主机调用 api 的前端开发人员提供一个具有 JWT 安全性的 Spring Boot Rest API。因此,当他调用 POST 请求时,他说他收到了 CORS 错误。所以我添加了部分

 @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {


        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");


        chain.doFilter(request, response);
    }

但他仍然收到错误。可能是什么原因。感谢任何帮助

OPTIONS https:my.domain/url 401 (Unauthorized)

当它是一个 POST 请求时。

控制器代码:

@RestController
public class RegistrationController {



    @Autowired
    @Qualifier("restTemplateUserRegitration")
    private RestTemplate restTemplateUserRegitration;
@RequestMapping(value="${user.endpoint}",produces={MediaType.APPLICATION_JSON_VALUE},method=RequestMethod.POST)
    public ResponseEntity<?> registerUser(@RequestBody Model ModelRequest){

                Map<String, Object> Status=new HashMap<String, Object>();
                FeedBackStatus = restTemplateUserRegitration.postForObject("http:serviceurl",registration/single",Model.class,Map.class );
                return ResponseEntity.ok(Status); 
    }
}

【问题讨论】:

  • See this link 可能会有所帮助,this link 也可以
  • 清除问题陈述。相关代码。没有不相关的代码。天哪,这是……一个好问题! (@joker21:他们只是相对罕见,似乎,来自新成员。不错的一个。)
  • 我认为问题出在服务器端,它没有激活 CORS,所以即使设置了你的标题你也不能打电话。
  • @canillas:OP 正在谈论服务器端。适应症:“我是一名后端开发人员,我正在提供 Spring Boot Rest API……” 引用 Java 代码。写回复。
  • 你做了什么调试?例如,您(来自request.getHeader("Origin"))发回的Access-Control-Allow-Origin 是否正确?是否有其他标头与您不允许的请求一起发送?

标签: java spring rest spring-boot


【解决方案1】:

先试试这个,应该允许所有来源,但是有安全风险。

response.setHeader("Access-Control-Allow-Origin", "*");

【讨论】:

  • OP 显然允许呼叫来自的来源,这是正确的。
  • @T.J.Crowder 正版问题,将 Access-Control-Allow-Origin 设置为与 getHeader("Origin") 相同的值有什么区别?
  • @jontro:可能不是一个重要的问题。上面的观点是 OP 已经将标头设置为有效值(几乎可以肯定),所以这不能回答问题。
【解决方案2】:

这是一种选择。不确定它是否优雅

 @Bean
  public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;
  }

把它放在任何spring bean中。

【讨论】:

  • 这如何回答这个问题?为什么OP需要这样做?代码转储不是有用的答案。
【解决方案3】:

你应该像这样实现一个过滤器:

public class CORSFilter extends OncePerRequestFilter {

    private final Logger LOG = LoggerFactory.getLogger(CORSFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
        LOG.info("Adding CORS Headers ........................");        
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
        res.addHeader("Access-Control-Expose-Headers", "xsrf-token");
        if ("OPTIONS".equals(req.getMethod())) {
         res.setStatus(HttpServletResponse.SC_OK);
        } else { 
         chain.doFilter(req, res);
        }        
    }
}

Cross Origin Request Blocked Spring MVC Restful Angularjs 的帖子中找到这个

希望对您有所帮助!

【讨论】:

    【解决方案4】:

    您可以创建自己的 CorsConfiguration

    @EnableWebSecurity
    class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    CorsConfigurationSource corsConfigurationSource = new CorsConfigurationSource() {
        @Override
        public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("http://localhost:63342");
            corsConfiguration.addAllowedHeader("Authorization");
            corsConfiguration.setAllowedMethods(Arrays.asList("POST", "GET"));
            corsConfiguration.setMaxAge(3600L);
            return corsConfiguration;
        }
    };
    

    并将其添加到配置中。

    .and().cors().configurationSource(corsConfigurationSource);
    

    并尝试使用此注释

    @CrossOrigin
    

    【讨论】:

      【解决方案5】:

      我也有过类似的经历。我们已经解决了如下问题。 这段代码添加在 securityConfiguration 中。 浏览器会在发送 POST 请求之前先发送 OPTIONS 请求。所以发送请求时,请求头中不包含授权头值,所以JWT过滤器判断用户未认证。

      @Override
      public void configure(WebSecurity web) throws Exception {
          web.ignoring()
                  .antMatchers(HttpMethod.OPTIONS);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-11
        • 2015-04-15
        • 2015-06-25
        • 2019-09-21
        • 2020-07-22
        • 2012-11-03
        • 2018-06-19
        • 2015-05-22
        相关资源
        最近更新 更多