预检的响应具有无效的HTTP状态代码:401 angular

Lau*_*ens 5 javascript java angularjs spring-boot

使用angular和Spring Boot,我们正在尝试为我们的服务添加身份验证,但出于某种原因,我们无法"打开"并从我们知道工作的URL中获取数据

角度:

this.getMismatches = function () {
    return $http({
            "async": true,
            "crossDomain": true,
            "url": GLOBALS.mismatchUrl,
            "method": "GET",
            "headers": {
                "authorization": "Basic YWRtaW46USNROawdNmY3UWhxQDlQA1VoKzU="
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

(目前登录令牌是硬编码的,用于测试目的)

休息服务:

@CrossOrigin(origins = "*")
@RequestMapping("/api/mismatch")
public List<Mismatch> home() {
    return service.getAll();
}
Run Code Online (Sandbox Code Playgroud)

CrossOrigin =*应该处理CORS问题,但这个失败的URL调用真的很奇怪.

我们尝试过的额外的东西:

'Access-Control-Allow-Methods', 'GET, POST, OPTIONS'
'Access-Control-Allow-Origin', '*'
'Content-Type', json plaintext jsonp etc

App.js:
    $httpProvider.defaults.headers.common = {};
    $httpProvider.defaults.headers.post = {};
    $httpProvider.defaults.headers.put = {};
    $httpProvider.defaults.headers.patch = {};
Run Code Online (Sandbox Code Playgroud)

fla*_*jpr 12

您在评论中提到,通过使用邮递员,您可以按预期获得响应.这是一个很好的起点.我怀疑通过使用curl -i -X URL终端的curl命令也会返回正确的响应.

如果邮递员工作正常,你必须意识到在发出请求之前,角度发送另一个请求,称为飞行前请求,它对服务器端的端点进行最小化检查.

此请求是OPTIONS类型请求.

首先,您必须确保您的dispatcherServlet接受OPTIONS请求.您可以通过在*.properties配置文件中指定它来实现此目的,例如:

spring.mvc.dispatch-options-request=true
Run Code Online (Sandbox Code Playgroud)

或者通过配置 web.xml

<servlet>
    <!--content eluded for clarity-->
    <init-param>
        <param-name>dispatchOptionsRequest</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)

将其配置为接受OPTIONS请求后,创建Filter.java并配置CORS过滤器.

您可以通过以下示例进行指导:

public class CorsFilter implements Filter{

@Override
public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain filterChain) throws IOException, ServletException {

    if(response instanceof HttpServletResponse){
        HttpServletResponse alteredResponse = ((HttpServletResponse)response);
        addCorsHeader(alteredResponse);
    }

    filterChain.doFilter(request, response);
}

private void addCorsHeader(HttpServletResponse response){
    //TODO: externalize the Allow-Origin
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
    response.addHeader("Access-Control-Allow-Headers", "Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
    response.addHeader("Access-Control-Max-Age", "1728000");
}

@Override
public void destroy() {}

@Override
public void init(FilterConfig filterConfig)throws ServletException{}
}
Run Code Online (Sandbox Code Playgroud)

最后,不要忘记将此过滤器web.xml与以下init-params一起添加.

<filter>
    <filter-name>cors-filter</filter-name>
    <filter-class>ai.surge.usrmngmtservice.util.cors.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Authorization,Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <!--<init-param>-->
        <!--<param-name>cors.preflight.maxage</param-name>-->
        <!--<param-value>1800</param-value>-->
    <!--</init-param>-->
</filter>
Run Code Online (Sandbox Code Playgroud)

你应该准备好了.