REST API - CORS 问题

Posted

技术标签:

【中文标题】REST API - CORS 问题【英文标题】:REST API - CORS Problems 【发布时间】:2019-05-22 04:55:04 【问题描述】:

CORS 对我来说是个问题..

我在http://localhost:8080 上使用 SPRING 制作了一个 REST API,我曾经在 http://localhost 上将此 API 与一个普通的 JS 站点一起使用,但在应用 OAuth2 之后,以下错误开始困扰我。

从源“http://localhost”访问“http://localhost:8080/oauth/token”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

在 OAuth(使用 AJAX 和 POSTMAN)之前,我可以在没有 CORS 问题的情况下访问 API,在应用 OAuth 之后,我可以仅在 POSTMAN 上使用 API,但我无法使用 AJAX。

我的 AJAX 代码:

function pronta()
    var username = "postmain"; // yes, I wrote wrong
    var password = "1234";  

    function make_base_auth(user, password) 
      var tok = user + ':' + password;
      var hash = btoa(tok);
      return "Basic " + hash;
    
    $.ajax
      (
        type: "POST",
        url: "http://localhost:8080/oauth/token",
        dataType: 'json',
        data: 
            'grant-type': 'password',
            'username': 'Tiago',
            'password': '123'
        ,
        header:'Authorization': make_base_auth(username, password), // I've tried on both manners. with header and with beforeSend
        beforeSend: function (xhr) 
            xhr.setRequestHeader('Authorization', make_base_auth(username, password)); 
        ,
        success: function ()
            alert('done'); 
        
    );

我的 CORS 过滤器(在 SPRING REST API 上)

    @Component
    public class SimpleCORSFilter implements Filter 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

        chain.doFilter(req, res);
    

    @Override
    public void init(FilterConfig filterConfig) 

    @Override
    public void destroy() 


过滤器在 OAuth 之前运行良好

一些想法发生了什么?

Tks

【问题讨论】:

当您在浏览器控制台上进行调试时,您是否得到响应所有 Access-Control-Allow-Origin = * 和.....您在 SimpleCorsFilter 中添加的所有内容? 是的。在 POSTMAN 和 Chrome 上(我可以在 Chrome DEVTools 的网络部分看到) OK 然后在“header:'Authorization': make_base_auth(username, password)”的标题上添加您在 SimpleCorsFilter 上添加的相同标题。 同样的错误,但“Access-Control-Request-Headers”更改为“access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,access -控制-最大年龄,授权”。之前只是“授权” 是的,看起来客户端的 cors 不允许与服务器端进行交互..如果您共享您的 repo,可能会有用.. 【参考方案1】:

我明白了。。 问题是每次我尝试发出请求时,之前都会提交一个预检请求(就像 REST 架构设计的那样)。

考虑到这一点,我只是准备服务器以允许 OPTIONS 方法。

像这样..

@Order(-1)    
@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
    

上课前不要忘记@Configuration注解。

【讨论】:

【参考方案2】:

可能会有帮助:

@Component
    public class SimpleCORSFilter implements Filter 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

   if ("OPTIONS".equalsIgnoreCase(request.getMethod())) 
            response.setStatus(HttpServletResponse.SC_OK);
         else 
            chain.doFilter(request, response);
        

    

@Override
public void init(FilterConfig filterConfig) 

@Override
public void destroy() 


【讨论】:

以上是关于REST API - CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

为 REST API 启用 CORS 支持

REST API 可以作为 CORS 问题的代理吗?

在 JIRA REST API 中启用 CORS

JIRA REST API cors

调用 REST API、JavaScript 时的 CORS 策略 [重复]

使用 Rest API Gateway lambda 集成 CORS 问题进行放大