新しくリリースされたHttpClient
を使用して、Angular 4
で基本認証を実装しようとしています。
公開された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
タブからです。
私は何を間違えていますか?どうすればこの作品を作ることができますか?
更新1:それでも動作しません:
2行を次のように変更しました。
headers = headers.append("Authorization", "Basic " + btoa("username:password"));
headers = headers.append("Content-Type", "application/x-www-form-urlencoded");
期待どおりにリクエストにヘッダーが含まれています。これはChrome
からのものです:
ただし、ポストコールはまだ失敗しています。
サーバー側のコードは次のとおりです。
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
からのものです:
どうやって進める ?
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
こんにちはあなたのバックエンドの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
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!");
});
私は同じ問題を抱えていて、承認ヘッダーはポストリクエストで送信されませんでした。これは私の認証機能でした
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;
}
)
);
現在は問題なく動作しています。