webpack服务器中的rest API调用(来自角度)返回401

Posted

技术标签:

【中文标题】webpack服务器中的rest API调用(来自角度)返回401【英文标题】:rest API call (from angular) in webpack server returns 401 【发布时间】:2018-02-03 13:10:39 【问题描述】:

Angular 应用,(在 webpack 开发服务器中执行),

它对部署在 JETTY 中的 Spring 应用程序进行 REST 调用(启用了 spring 安全性/BASIC 身份验证)。

通过angular调用http://localhost:8085/myapi/api/login时,响应为:401 Unauthorized (请求方法是OPTIONS,虽然指定为POST)

已尝试发布与此相关的大多数解决方案(从 Angular、Spring Security 和 web.xml(jetty) 端启用/发送 CORS 标头。

需要什么?

Chrome 中的错误对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头

角度

let headers =  new Headers();
headers.append("Authorization", "Basic " + btoa("test_user:test_user"));
headers.append("X-Requested-With", "XMLHttpRequest");
headers.append("withCredentials", "true");
//headers.append("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT, DELETE");
//headers.append("Access-Control-Allow-Origen", "*");

let options = new RequestOptions(headers: headers);
this.http.post("http://localhost:8085/myapi/api/services/login", 
               JSON.stringify(), options);

春季安全

<sec:http auto-config="true" use-expressions="true" 
entry-point-ref="authenticationEntryPoint">
    <sec:form-login />
    <sec:http-basic />
    <sec:logout />
    <sec:intercept-url pattern="/**" access="permitAll" />
    <!-- corsHandler: filter (OncePerRequestFilter) that adds Access-Control-Allow-Origin header -->
    <sec:custom-filter ref="corsHandler" position="PRE_AUTH_FILTER"/>
    <sec:cors /> 
</sec:http>

web.xml

<filter>
    <filter-name>cross-origin</filter-name>
    <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
    </init-param>
   <init-param>
       <param-name>allowedMethods</param-name>
       <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
   </init-param>
  <init-param>
       <param-name>allowedHeaders</param-name>
       <param-value>Origin,Content-Type,Accept,authorization,X-Requested-With</param-value>
   </init-param>
</filter>
<filter-mapping>
    <filter-name>cross-origin</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

webpack 服务器:

  devServer: 
    historyApiFallback: true,
    stats: 'minimal',
        headers: 
            'Access-Control-Allow-Origin': '*'
         
  

有过滤器(servlet 过滤器)和 Spring 拦截器设置来添加 Access-Control-Allow-Origen 标头,但没有执行。

【问题讨论】:

【参考方案1】:

最终的解决方案是在 webpack 开发服务器中创建一个代理

代理避免了 CORS 问题(代理:...)。如果 Angular 应用程序正在运行,则其余 api 的 URL 已更新到同一台机器: this.http.post("http://localhost:8081/myapi/api/services/login", ...):

webpack 代理:

devServer: 
    historyApiFallback: true,
    stats: 'minimal',
    headers: 
        'Access-Control-Allow-Origin': '*'
    ,
    proxy: 
       '/myapi/api/**': 
            target: 'http://localhost:8085',
            secure: false              
        
    

在 Angular 中,需要针对 rest 映射方法进行带有身份验证标头的 HTTP 调用。

@PostMapping("/login")
public ResponseEntity login() 
    return new ResponseEntity<>(HttpStatus.OK);

一旦不存在 CORS 问题,调用这个 rest 方法(通过代理)似乎可以正常工作。

不明白为什么 CORS 配置在这种情况下不起作用: 此解决方案不需要上述问题中与 CORS 相关的大多数代码

【讨论】:

以上是关于webpack服务器中的rest API调用(来自角度)返回401的主要内容,如果未能解决你的问题,请参考以下文章

来自 html 的 REST API 调用不起作用

Spring boot REST API 仅接受来自 Angular 前端的调用

在节点中创建 REST API 时,如何将来自对外部网站的请求的 http 响应流式传输到原始 api 调用?

如何阻止来自未知域/IP 对我的 REST API 的调用?

如何使用 Retrofit @Query 调用 REST API

来自 REST API 调用的 PowerBI XML 数据源有时会返回“表”数据类型