2017-09-04 3 views
6

각도로 표시된 문서에서 각도 httpclient은 게시 요청의 헤더에 쿠키 XSRF-TOKEN의 값을 자동으로 보냅니다. Documentation linkangular4 httpclient csrf가 x-xsrf 토큰을 보내지 않음

그러나 나를 위해 헤더를 보내지 않습니다. 여기 쿠키

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

CSRF 토큰을 모든 요청 또는 데이터 변경 요청 (POST, PUT, DELETE)에만 추가합니까? – 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', })