2017-09-04 16 views
6

角度のある文書では、角度httpclientは、投稿要求のヘッダーX-XSRF-TOKENにクッキーXSRF-TOKENの値を自動的に送信することが記載されています。 Documentation linkangular4 httpclient csrfはx-xsrf-tokenを送信しません

しかし、私のためにヘッダーを送信しません。ここではクッキー

router.get('/set-csrf',function(req,res,next){ 
    res.setHeader('Set-Cookie', "XSRF-TOKEN=abc;Path=/; HttpOnly; SameSite=Strict");  
    res.send(); 
    }) 

を設定する

Nodejsコードは、私がapp.module.tsでのHTTPClientを使用していた私のコードです

imports: [ 
    HttpClientModule 
] 

**上記のコードは単なるデバッグ用です目的。私はset-csrfエンドポイントを持っていません。

ただし、投稿リクエストを送信しても、ヘッダーは送信されません。私はデバッグできません。

私はgithubのリポジトリにもこの問題を追加しました。 HttpXsrfInterceptorは、リクエストがGETかHEADか、あるいはhttpで始まっているかどうかをチェックします。 trueの場合、ヘッダーの追加はスキップされます。ここで

コードは、彼らがHTTP/Sの部分はスキップされている理由私はわからないHttpXsrfInterceptor class

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

です。ここに私ですissue in github

+0

CORSリクエストを使用していますか? – Alexandr

+0

"Access-Control-Allow-Headers"、 "*" ' – netuser

+1

という見出しを追加しました。角度は、http [s]リンクを別の方法で処理する必要があります。たとえば、各ドメインの最後のcsrfトークンを個別に格納します。おそらく、別のインターセプタウインチがcsrfをこのように扱うのは良いことでしょうか? – Alexandr

答えて

8

あなたが探しているものはHttpClientXsrfModuleです。

詳細はこちらhttps://angular.io/api/common/http/HttpClientXsrfModuleをご覧ください。

あなたの使い方は次のようにする必要があります:あなたのコードが絶対URL経由でAPIをターゲットにしている場合

imports: [ 
HttpClientModule, 
HttpClientXsrfModule.withConfig({ 
    cookieName: 'My-Xsrf-Cookie', // this is optional 
    headerName: 'My-Xsrf-Header' // this is optional 
}) 
] 

また、デフォルト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 } 
] 
+0

すべての要求またはデータ変更要求(POST、PUT、DELETE)のみにCSRFトークンを追加しますか? – dzejdzej

+0

あなたはGETを使ってCSRFトークンを取得するので、GETはそれをあなたのために返します(もちろん、ユーザー認証に関して)。POST、PUT、 DELETE、PATCHはデータを変更しており、CSRFが重大であることがあります。 –

+0

私が意味したのは、すべてのリクエストにトークンが設定されていることを指定したコードで、GETリクエストであっても意味があります。私はそれが意図されているとは思わない。 – dzejdzej

0

私は正しい方法がwithOptionsであると仮定します。 withConfigを使用してエラーが発生しましたProperty 'withConfig' does not exist on type 'typeof HttpClientXsrfModule'.これはドキュメントの入力上の問題です。代わりに "withOptions"を使用する必要がありますHttpClientXsrfModule.withOptions({ cookieName: 'My-Xsrf-Cookie', headerName: 'My-Xsrf-Header', })

関連する問題