Ionic 2を使用するAngular 2アプリケーションがあり、ASP.NET Core APIサーバーにHttp PUTを送信しています。リクエストの送信に使用しているメソッドは次のとおりです。
public update(student: Student): Promise<Student>
{
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);
const url = `${this.studentsUrl}`;
return this.http
.put(url, JSON.stringify(student), { headers: headers })
.toPromise()
.then(() => student)
.catch(this.handleError);
}
ヘッダーオブジェクトに認証キー/値を設定しています。
しかし、サーバーでこのリクエストを受信すると、ヘッダーに認証キーが見つかりません。
図からわかるように、ヘッダーには多くのキーがありますが、クライアントアプリケーションのヘッダーに手動で追加したコンテンツキーと認証キーはありません。
私は何を間違えていますか?
Http.put()のリクエストオプションのパラメータは、実際にはRequestOptionsタイプである必要があります。次のようなものを試してください:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);
let options = new RequestOptions({ headers: headers });
return this.http
.put(url, JSON.stringify(student), options)
ヘッダーを設定するを手動で設定するか、HTTPインターセプターを作成するリクエストが行われるたびにヘッダーを自動的に設定します。
ヘッダーの設定:(
http
.post('/api/items/add', body, {
headers: new HttpHeaders().set('Authorization', 'my-auth-token'),
})
.subscribe();
ヘッダーの設定:
this.http
.post('api/items/add', body, {
headers: new HttpHeaders({
'Authorization': 'my-auth-token',
'x-header': 'x-value'
})
}).subscribe()
ローカル変数(再び不変のインスタンス化)
let headers = new HttpHeaders().set('header-name', 'header-value');
headers = headers.set('header-name-2', 'header-value-2');
this.http
.post('api/items/add', body, { headers: headers })
.subscribe()
HttpHeadersクラスは不変であるため、すべてのset()は新しいインスタンスを返し、変更を適用します。
Angular docs から。
@ angular/common/httpの主要な機能はインターセプトです。これは、アプリケーションとバックエンドの間に位置するインターセプターを宣言する機能です。アプリケーションが要求を行うと、インターセプターはそれをサーバーに送信する前に変換し、インターセプターはアプリケーションがそれを見る前に応答を変換できます。これは、認証からログ記録まですべてに役立ちます。
Angular docs から。
アプリケーション全体で必ず@angular/common/http
を使用してください。そうすれば、リクエストはインターセプターによってキャッチされます。
ステップ1、サービスの作成:
import * as lskeys from './../localstorage.items';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
@Injectable()
export class HeaderInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (true) { // e.g. if token exists, otherwise use incomming request.
return next.handle(req.clone({
setHeaders: {
'AuthenticationToken': localStorage.getItem('TOKEN'),
'Tenant': localStorage.getItem('TENANT')
}
}));
}
else {
return next.handle(req);
}
}
}
ステップ2、モジュールに追加:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HeaderInterceptor,
multi: true // Add this line when using multiple interceptors.
},
// ...
]
便利なリンク:
Interceptors を使用するとうまくできます。すべてのサービスでオプションを設定する必要はなく、すべてのエラー応答を管理する必要もありません。2つのインターセプターを定義するだけです(1つはサーバーにリクエストを送信する前に何かを行い、もう1つはサーバーの応答をサービスに送信する前に何かを行う)
app.moduleで、「@ angular/common/http」からHTTP_INTERCEPTORSをインポートします。次に、プロバイダーにインターセプター(AuthInterceptorおよびresponseInterceptor)を追加します。これを行うと、アプリはすべてのhttpClient呼び出しでインターセプターを考慮します。
ログインhttp応答(httpサービスを使用)で、トークンをlocalStorageに保存します。
次に、すべてのサービスに対してhttpClientを使用します。
私のgithub proyectでいくつかの良い習慣を確認できます here
これは、Angularからヘッダーをインポートすることで簡単に解決できます。
import { Http, Headers } from "@angular/http";
私たちは次のようなソリューションを使用しました。
this.http.get(this.urls.order + '&list', {
headers: {
'Cache-Control': 'no-cache',
}
}).subscribe((response) => { ...
参照 ここ
タイプミスがあります。
変更:headers.append('authentication', ${student.token});
To:headers.append('Authentication', student.token);
注:認証は大文字です