web-dev-qa-db-ja.com

Angular 4.3 HTTPClient基本認証が機能しない

新しくリリースされたHttpClientを使用して、Angular 4で基本認証を実装しようとしています。

公開されたSpring AP​​Iを使用して、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:それでも動作しません:

2行を次のように変更しました。

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 stuffに到達することはありません。 authCredentialsnullです。

これはchromeからのものです:

enter image description here

どうやって進める ?

21
Vicky

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

26

こんにちはあなたのバックエンドのCOR設定

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レポのサンプルデモを確認することもできます springmvc with angular2/4

2
Robert

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

私は同じ問題を抱えていて、承認ヘッダーはポストリクエストで送信されませんでした。これは私の認証機能でした

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

投稿には本文として2番目の引数、ヘッダーとして3番目の引数が必要であることは知りませんでした。この質問を受け取った後、私は質問自体から、本文に何も持っていないため、2番目の引数を空の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;
   }
 )
);

現在は問題なく動作しています。

0
Mohammad Anas