Angular 4.3 HTTPClient基本授权不起作用

时间:2017-08-26 11:02:51

标签: java spring angular google-chrome tomcat

我正在尝试使用新发布的Angular 4HttpClient中实施基本授权。

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

我的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

然而,后调用仍然失败。

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

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 stuffauthCredentialsnull

这来自chrome

enter image description here

如何进行?

4 个答案:

答案 0 :(得分:25)

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 Docs

答案 1 :(得分:2)

您的后端队员可以配置吗

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);
     }
 }

您的角度请求应该是那样,

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 repo示例演示 spring mvc with angular2/4

答案 2 :(得分:0)

使用RequestOptions为您的帖子请求设置标题。

    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!");
       });

答案 3 :(得分:0)

我遇到了同样的问题,并且授权标头与发布请求不匹配。 这是我的身份验证功能

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需要第二个参数作为主体,第三个参数作为标题。 出现此问题后,我从问题本身中发现,我需要发送第二个参数作为空白json,因为我体内没有任何东西。

这是上述验证功能的正确代码

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;
   }
 )
);

现在哪个工作正常。