Search code examples
angulartypescriptcookiesangular-httpclient

Prevent HttpClient from reading cookies on PUT, POST & PATCH


How can I prevent my Angular app from trying to read document.cookie on PUT / POST and PATCH requests from the HttpClient?

  • My app runs in an iframe within another web app where accessing cookies is not allowed!
    I can't control this environment / app.
  • GET requests work without any problems.
  • I'm using Angular 6.0.2

Error

put, post & patch request from the HttpClient produce the following error.

backend.service.ts:127 DOMException: Failed to read the 'cookie' property from 'Document': The document is sandboxed and lacks the 'allow-same-origin' flag. at HttpXsrfCookieExtractor.push../node_modules/@angular/common/fesm5/http.js.HttpXsrfCookieExtractor.getToken (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:27596:37) at HttpXsrfInterceptor.push../node_modules/@angular/common/fesm5/http.js.HttpXsrfInterceptor.intercept (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:27633:39) at HttpInterceptorHandler.push../node_modules/@angular/common/fesm5 /http.js.HttpInterceptorHandler.handle (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:27004:33) at HttpInterceptingHandler.push../node_modules/@angular/common/fesm5/http.js.HttpInterceptingHandler.handle (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:27677:27) at MergeMapSubscriber.project (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:26755:184) at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:110070:27) at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:110060:18) at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:101403:18) at Observable._subscribe (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:104821:20) at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (http://localhost:8080/44812272_a91e_4126_ad7b_6a54454…_sc-lightcontrol.jar/vendor.js:100628:25)

Code

putTest(), postTest() and patchTest() fail with the above Exception.
getTest() works.

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
  withCredentials: false
};

@Injectable({ providedIn: 'root' })
export class BackendService {

  constructor(
    private http: HttpClient,
    private messageService: MessageService
  ) { }

  putTest(): Observable<any> {
    console.log('PUT test');
    return this.http.put(BackendUrl.updateDeviceToControl, mockDevicePropertyData, httpOptions)
      .pipe(
        tap(_ => console.log('Success')),
        catchError(this.handleError<any>('PUT test'))
      );
  }

  patchTest(): Observable<any> {
    console.log('PATCH test');
    return this.http.patch(BackendUrl.updateDeviceToControl, mockDevicePropertyData, httpOptions)
      .pipe(
        tap(_ => console.log('Success')),
        catchError(this.handleError<any>('PATCH test'))
      );
  }

  postTest(): Observable<any> {
    console.log('POST test');
    return this.http.post(BackendUrl.updateDeviceToControl, mockDevicePropertyData, httpOptions)
      .pipe(
        tap(_ => console.log('Success')),
        catchError(this.handleError<any>('POST test'))
      );
  }

  getTest(): Observable<any> {
    console.log('GET test');
    return this.http.get(BackendUrl.updateDeviceToControl)
      .pipe(
        tap(_ => console.log('Success')),
        catchError(this.handleError<any>('GET test'))
      );
  }
}

Solution

  • Put / Post & Patch requests work if I disable XSRF protection support for outgoing requests, which is enabled by default and tries to read the cookie XSRF-TOKEN.

    @NgModule({
      imports: [
        HttpClientModule,
        HttpClientXsrfModule.disable(),
      ]
    })
    

    HttpClientXsrfModule.disable()