angularドキュメンテーションでは、angular httpclient
は自動的にcookieの値を送信しますXSRF-TOKEN
ヘッダー内X-XSRF-TOKEN
投稿リクエスト。 ドキュメントリンク
ただし、ヘッダーは送信されません。ここに私のコードがあります
Cookieを設定するNodejsコード
router.get('/set-csrf',function(req,res,next){
res.setHeader('Set-Cookie', "XSRF-TOKEN=abc;Path=/; HttpOnly; SameSite=Strict");
res.send();
})
App.module.tsでhttpclientを使用しました
imports: [
HttpClientModule
]
**上記のコードはデバッグ用です。 set-csrfエンドポイントがありません。
ただし、投稿要求を送信するときにヘッダーは送信されません。デバッグできません。
angular too。HttpXsrfInterceptorは、リクエストがGETまたはHEADかどうか、またはhttpで始まるかどうかをチェックします。trueの場合、ヘッダーの追加をスキップします。
HttpXsrfInterceptorクラス のコードを次に示します
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const lcUrl = req.url.toLowerCase();
// Skip both non-mutating requests and absolute URLs.
// Non-mutating requests don't require a token, and absolute URLs require special handling
// anyway as the cookie set
// on our Origin is not the same as the token expected by another Origin.
if (req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') ||
lcUrl.startsWith('https://')) {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(this.headerName)) {
req = req.clone({headers: req.headers.set(this.headerName, token)});
}
return next.handle(req);
}
彼らがhttp/sの部分をスキップした理由はわかりません。ここに私の githubの問題
探しているのはHttpClientXsrfModule
です。
詳細については、こちらをお読みください: https://angular.io/api/common/http/HttpClientXsrfModule 。
使用法は次のようになります。
imports: [
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'My-Xsrf-Cookie', // this is optional
headerName: 'My-Xsrf-Header' // this is optional
})
]
さらに、コードが絶対URLを介してAPIをターゲットにしている場合、デフォルトのCSRFインターセプターはそのままでは機能しません。代わりに、絶対ルートを無視しない独自のインターセプターを実装する必要があります。
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
最後に、プロバイダーに追加します。
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, multi: true }
]
正しいメソッドはwithOptions
だと思います。 withConfigを使用して、エラー_Property 'withConfig' does not exist on type 'typeof HttpClientXsrfModule'.
_が発生しました。これはドキュメントのタイピングの問題です。代わりに「withOptions」を使用する必要がありますHttpClientXsrfModule.withOptions({ cookieName: 'My-Xsrf-Cookie', headerName: 'My-Xsrf-Header', })
最近のAngularバージョンを使用すると、次の問題に遭遇しました。 「X-XSRF-TOKEN」ですので、ここで私のために動作する上記のMiroslavのコードを少し修正したバージョンを示します。
@Injectable()
export class HttpXSRFInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'XSRF-TOKEN';
const respHeaderName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(respHeaderName, token) });
}
return next.handle(req);
}
}