Angular 6を使用しています。HTTPインターセプターは、送信要求にベアラートークンを適用するように構成されています。
製品ビルドでは、ヘッダーを適用した後にコンソールにダンプすることにより、ヘッダーが適用されていることを確認しました。
なぜHTTPリクエストから除外されるのかわかりません。
environment
ファイルに違いはありません。
他に何を見ればいいですか?
---(
これを修正するにはどうすればよいですか?
最初はローカル環境とステージング環境の間の問題だと思っていましたが、次にng serve --prod
ローカルで同じ結果を見ました。
つまり、本番ビルドと開発ビルド以外はすべて同じです。
jwt-interceptor:
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.token}`
}
});
console.log('headers:', request.headers); // <---- I can see headers in console output
}
return next.handle(request);
}
}
app.module.ts
import { HttpClientModule, HttpClient, HttpInterceptor } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { PortalModule } from '@angular/cdk/portal';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { JwtInterceptor } from './jwt-interceptor';
import { ENV } from '../environments/environment';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
...
import { myApiService } from './services/my-api.service';
import { myModalComponent } from './_components/my-modal/my-modal.component';
import { myModalService } from './services/my-modal.service';
import { AngularLaravelEchoModule, PusherEchoConfig, EchoInterceptor } from 'angular-laravel-echo/angular-laravel-echo';
export const echoConfig: PusherEchoConfig = {
userModel: 'App.User',
notificationNamespace: 'App\\Notifications',
options: {
broadcaster: 'pusher',
key: ENV.pusherConfig.key,
cluster: ENV.pusherConfig.cluster,
Host: ENV.apiRoot,
authEndpoint: ENV.apiRoot + '/broadcasting/auth',
}
};
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
HttpClientModule,
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
PortalModule,
AngularLaravelEchoModule.forRoot(echoConfig)
],
providers: [
myApiService,
myModalService,
{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: EchoInterceptor,
multi: true
}
],
bootstrap: [AppComponent],
entryComponents: [
myModalComponent
]
})
export class AppModule {
}
このアプリをStackBlitzで作成しましたが、ng serve --prod
を使用してローカルで実行すると、問題なく動作します。
https://stackblitz.com/edit/angular-yzckos
ダウンロードして実行し、ネットワークタブにundefined
が表示されるかどうかを確認します。ヘッダーが適切に送信されていることが確認できる場合は、コードに何かおかしな点があります。
以下を試してください:
1- `ng serve --port = aDifferentPort // 2098のように実行してみてください
そのポートで何かが実行されており、認証ヘッダーを送信している可能性があります
2- AOTをfalseにしてみてください。問題が発生する理由は考えられません。
3-ブラウザにAuthヘッダーを上書きする拡張機能がないことを確認するか、他のブラウザを試してください
4-他のHTTPインターセプターをオフにします。おそらくそのうちの1つが予期しない動作をします
5-ヘッダー名をAuthorizaion
からMyAuthorization
に変更します。未定義になっていないかどうかを確認し、未定義になっている場合は、何か、package.json
を確認し、本番サーブで他に何も実行していないことを確認してください。
6-JwtInterceptor
を完全にオフにして、認証ヘッダーをHTTP
リクエストに添付してみてください。それでもundefined
が表示されるかどうかを確認してください。
7-何も役に立たなかった場合は、本当に私たちにもっとコードを送る必要があります:)
私はこれについて考えがあります-それがうまくいくかもしれないかどうか確認してください
HttpHeaders
は変更可能です。ヘッダーを追加すると、既存のヘッダーが更新されて値が追加されるため、ヘッダーの追加で問題が発生するため、以下の方法に従います。
private getHeaders(): HttpHeaders {
let headers = new HttpHeaders();
headers = headers.append("Content-Type", "application/json");
return headers;
}
それ以来、新しいヘッダーを追加してオブジェクトを元のオブジェクトに割り当て、オブジェクトを返しました-これは、製品ビルドと開発ビルドの両方でうまく機能しました
ただし、あなたの場合、HttpInterceptor
で上記と同じ方法を使用するか、以下のサンプルのようにsetheaders
をheaders
に変更してみてください。
if (currentUser && currentUser.token) {
request = request.clone({
headers: new HttpHeaders({
Authorization: `Bearer ${currentUser.token}`
})
});
console.log('headers:', request.headers);
}
これで両方のビルドであなたの問題が解決すると確信しています-うまくいかない場合は私に知らせてください-うまくいくことを願っています-ハッピーコーディング!!
実際のAPI呼び出しでヘッダーを設定してみることはできますか?同様に、例:
put(path: string, body: Object = {}): Observable<any> {
return this.http.put(`${environment.api_url}${path}`, body, { headers:
this.setHeaders() })
.map((res: Response) => {
return res;
});
}
private setHeaders(): HttpHeaders {
const headersConfig = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.oauthService.getAccessToken()
};
return new HttpHeaders(headersConfig);
}
そしてインターセプターは
request.clone()
request.clone()
メソッドでヘッダーを手動で複製してみてください。これは私にとってうまくいくものです:
export class HttpHeaderInterceptor implements HttpInterceptor {
// ...
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// ...
const clonedRequest = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + currentUser.token)
});
return next.handle(clonedRequest).pipe(
catchError(err => { /* Error handling here */ })
);
}
}
これが少し役に立てば幸いです:-)
サーバーがAuthorization
ヘッダーを完全に無視する本番環境でもほぼ同様の問題が発生しました。 Angular 6はAuthorization
ヘッダーを適切に送信しますが、サーバーは完全に除去します(ほとんどの本番サーバー、共有ホスティングのセキュリティ設定により)。これはあなたが探している答えではないかもしれません。しかし、私はあなたに手がかりを与えたかっただけです。
したがって、最後にこれを機能させるには、Php-Auth-Digest
などの別のヘッダーパラメーターを次のように使用する必要がありました。
request = request.clone({
setHeaders: {
"Php-Auth-Digest": `Bearer ${currentUser.token}`,
}
});
回避策として、ヘッダーパラメータ名を変更してみてください。
乾杯!