【问题标题】:how to send "X-CSRF-TOKEN" with response header in angular4如何在angular4中发送带有响应头的“X-CSRF-TOKEN”
【发布时间】:2018-05-08 04:29:43
【问题描述】:

我目前正在开发一个 Angular4 应用程序。现在我想实现 XSRF 保护。在响应头 cookie 中,我得到“XSRF-TOKEN”,我需要在下一个请求头 cookie 中发送“X-XSRF-TOKEN”。正如official Angular document 中提到的,Angular 正在处理这个问题。但就我而言,角度并没有处理它。所以我创建了以下自定义 XsrfInterceptor 来附加“X-XSRF-TOKEN”和响应头。

import { NgModule, Injectable } from '@angular/core';
import { Observable } from "rxjs/Observable";
import { HttpRequest, HttpHandler, HttpEvent, HttpXsrfTokenExtractor, HttpInterceptor } from "@angular/common/http";

@Injectable()
export class XsrfInterceptor implements HttpInterceptor {

    constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const headerName = 'X-XSRF-TOKEN';
        console.log("xsrf intercepter called");
        let requestToForward = req;
        let token = this.tokenExtractor.getToken() as string;
        console.log(token);
        if (token !== null) {
            requestToForward = req.clone({ setHeaders: {headerName: token } });
        }
        return next.handle(requestToForward);
    }
}

在我的主模块中,我将它包含在提供程序中,

providers: [
    LoginService,
    AuthGuardLogin,
    { provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor,  multi: true }      
], 

但不幸的是,它不起作用。我认为我的应用程序没有调用自定义拦截器的拦截方法(它没有打印 console.log('xsrf intercepter called'))。

我的 http 标头如下:

let httpHeader = new RequestOptions({
            headers: new Headers({
                'Content-Type': 'application/json',
                'x-auth-token': this.authToken
            })
        })

在响应头中:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Access-Control-Allow-Origin, Access-Control-Allow-Headers, Accept, X-XSRF-TOKEN, XSRF-TOKEN, X-Requested-By, Content-Type, Origin, Authorization, X-Requested-With, x-auth-token, OPTIONS
Access-Control-Allow-Methods:POST, GET, PUT, OPTIONS
Access-Control-Allow-Origin:http://localhost:7070
Access-Control-Expose-Headers:x-auth-token, XSRF-TOKEN, X-XSRF-TOKEN
Access-Control-Max-Age:3600
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Date:Fri, 24 Nov 2017 06:42:20 GMT
Expires:0
Pragma:no-cache
Referrer-Policy:same-origin
Set-Cookie:XSRF-TOKEN=63f66e2a-1ad0-4641-8f36-27c16734a676;path=/mfleet;HttpOnly
Transfer-Encoding:chunked
x-auth-token:8d06b1da-c35b-42ea-ac28-eae51f3dd74d
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

下一个请求标头:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Connection:keep-alive
Content-Type:application/json
Cookie:XSRF-TOKEN=63f66e2a-1ad0-4641-8f36-27c16734a676  **//this should be X-XSRF-TOKEN**
Host:localhost:7070
Referer:http://localhost:7070/dist/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
x-auth-token:8d06b1da-c35b-42ea-ac28-eae51f3dd74d

我正在使用以下版本的角度库:

"@angular/animations": "^4.4.5",
    "@angular/cdk": "^2.0.0-beta.8",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "4.0.0",
    "@angular/material": "^2.0.0-beta.8",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",

【问题讨论】:

    标签: angular cookies interceptor csrf-protection x-xsrf-token


    【解决方案1】:

    只有在您导入正确的模块时,Angular 才会处理 XSRF。并且仅从 4.3 开始实现新的 http 客户端和拦截器。

    您应该将 angular 更新到至少 4.3.0(我建议升级到 5.0.0,因为这是 material2 的最新版本所需要的),然后在您的应用程序模块中导入 HttpClientXsrfModule。然后它应该开箱即用。

    问候

    【讨论】:

    • 感谢您的帮助。我已经按照你的建议实施了。但它不起作用。如果我遗漏了什么,请检查以下代码并纠正我? “@angular/animations”:“4.4.5”、“@angular/cdk”:“^2.0.0-beta.8”、“@angular/common”:“4.3.0”、“@angular/compiler” :“4.3.0”、“@angular/core”:“4.3.0”、“@angular/forms”:“4.3.0”、“@angular/http”:“4.3.0”、“@angular/材料”:“^2.0.0-beta.8”、“@angular/platform-b​​rowser”:“4.3.0”、“@angular/platform-b​​rowser-dynamic”:“4.3.0”、“@angular/路由器": "4.3.0",
    • imports:[ //其他模块... HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN' }) ]
    • 您是否使用新模块 HttpClientModule 进行 https 调用?拦截器将仅与此模块一起使用
    • 让 token = this.tokenExtractor.getToken() 作为字符串;总是返回空值。我错过了什么吗?
    • 由于您的配置是标准的(参见:angular.io/guide/http#security-xsrf-protection),您应该只导入 HttpClientModule、HttpClientXsrfModule 等等。您不必创建拦截器,因为 HttpClientXsrfModule 会为您执行此操作,并且不必手动调用 tokenExtractor。
    猜你喜欢
    • 2018-02-12
    • 2015-02-11
    • 2017-05-14
    • 2021-05-14
    • 2016-09-25
    • 1970-01-01
    • 2014-04-11
    相关资源
    最近更新 更多