Angular 4.3 HTTPClient基本身份验证无法工作

25

我正在尝试使用新发布的HttpClientAngular 4中实现基本授权。

我正试图连接到运行在Tomcat上公开了REST API的Spring应用程序。

我在LoginComponent中有以下代码:

onSubmit(user){
   console.log(user);
   const body = JSON.stringify({username: user.userName, password: user.password});

   let headers = new HttpHeaders();
   headers.append("Authorization", "Basic " + btoa("username:password"));
   headers.append("Content-Type", "application/x-www-form-urlencoded");

   this.http.post('my url here',body, {headers: headers}).subscribe(response => {
         console.log(response);
   }, err => {
      console.log("User authentication failed!");
   });
}

然而,该请求根本没有添加Authorization头。

这是来自Chrome工具中的Network选项卡:

enter image description here

我做错了什么?如何使它工作?


更新1:仍然无法正常工作:

我将我的两行更改如下:

headers = headers.append("Authorization", "Basic " + btoa("username:password"));
headers = headers.append("Content-Type", "application/x-www-form-urlencoded");

我得到了预期的请求头。这是来自Chrome

enter image description here

然而,POST调用仍然失败。

在服务器端,我的代码是:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    String authCredentials = request.getHeader("Authorization");

    if(authCredentials == null) {
        logger.info("Request with no basic auth credentials {}", request.getRequestURL());
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        return;
    }

    // do my stuff
}

调用从未到达do my stuff,“authCredentials”为null

这是来自chrome的:

enter image description here

该怎么办?


你从哪个包中导入了 http - @angular/common/http 还是 @angular/http - Ajit Soman
@AjitSoman:@angular/common/http... - Vicky
Ben的答案对你有用吗?在控制台上有关于跨域资源共享(CORS)的任何错误吗? - Ajit Soman
我在谷歌浏览器中安装了一个CORS插件,以解决调试和开发模式下的CORS问题。 - John
4个回答

31

HttpHeaders 是不可变的,因此每次调用时需要将函数的结果赋值给 headers 对象来覆盖它。

let headers = new HttpHeaders();
headers = headers.append("Authorization", "Basic " + btoa("username:password"));
headers = headers.append("Content-Type", "application/x-www-form-urlencoded");

来源: Angular文档


将函数的结果分配给每次调用时覆盖头对象。您能详细说明一下吗? - Vicky
看一下代码,不要简单地使用 headers.append(),而是要使用 headers = headers.append(),因为 headers.append() 会创建一个新的 headers 对象,而你之前没有使用它。 - Ben Kolya Mansley
1
哦!抱歉!现在才注意到…我还以为你只复制粘贴了我的两行代码!!我会试一下的…谢谢! - Vicky

2

你好,你的后端CORS配置可以吗?

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class RestConfig {
    @Bean
    public CorsFilter corsFilter() {
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
     }
 }

你的 Angular 请求应该像这样:

import { Http , Headers, Response } from '@angular/http';
let headers = new Headers();
headers.append("Authorization", "Basic " + btoa("username:password"));
headers.append("Content-Type", "application/x-www-form-urlencoded");

你也可以查看githup仓库的示例演示spring mvc with angular2/4


1

我遇到了同样的问题,授权头没有随POST请求一起发送。这是我的身份验证函数。

authenticate(username, password) {
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });

return this.httpClient.post<any>('<your-login-url>',{headers}).pipe(
 map(
   userData => {
    sessionStorage.setItem('username',username);
    return userData;
   }
 )
);

我不知道post需要第二个参数作为body,第三个参数作为headers。 在看到这个问题后,我从问题本身发现需要发送一个空的json作为第二个参数,因为我没有任何内容。 以下是上述authenticate函数的正确代码。
authenticate(username, password) {
const headers = new HttpHeaders({ Authorization: 'Basic ' + btoa(username + ':' + password) });

return this.httpClient.post<any>('<your-login-url>',{},{headers}).pipe(
 map(
   userData => {
    sessionStorage.setItem('username',username);
    return userData;
   }
 )
);

现在正常工作。

0

使用RequestOptions来设置您的POST请求头。

    import { Http,Headers,RequestOptions } from '@angular/http';
    ..
    ..
    let headers = new Headers();
    headers.append("Authorization", "Basic " + btoa("username:password"));
    headers.append("Content-Type", "application/x-www-form-urlencoded");

    let options = new RequestOptions({ headers: headers });
    this.http.post('my url here',body, options).subscribe(response => {
             console.log(response);
       }, err => {
          console.log("User authentication failed!");
       });

谢谢,但我正在尝试使用新版本的HttpClient(Angular 4.3)。 - Vicky
RequestOptions与@angular/common/http中的HttpHeaders不兼容。 - Vicky
RequestOption 只能与旧包 @angular/httphttp 模块一起使用。 - Ajit Soman
你的项目中有使用Spring Security吗?此外,你在后端配置了CORS过滤器吗? - Ajit Soman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接