Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 set withCredentials to true with every HttpClient call

If you want the credentials (cookie authentication token) to be passable through a call, you need to add { withCredentials: true } in your httpclient call. Something like this:

import { HttpClient  } from '@angular/common/http';
...
constructor(private httpclient: HttpClient) { }

this.httpclient.get(url, { withCredentials: true })

I would just like to know if there is a way to preset { withCredentials: true } with every single call. I don't want to have to add { withCredentials: true } every time I make a call.

Here is a related question, but I am not sure if this works with HttpClient?

like image 796
Freddy Bonda Avatar asked Oct 16 '18 11:10

Freddy Bonda


People also ask

What is withCredentials true in Angular?

withCredentials property is a boolean value that indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-origin requests.

What type does HttpClient get method return?

Now HttpClient.get() returns an Observable of type HttpResponse rather than just the JSON data contained in the body. As you can see, the response object has a body property of the correct type.

What data format is the response from the HttpClient get () method and how do you read its contents?

The responseType option indicates the format of the data returns from the http request. Default responseType of HttpClient. get() method is “json”. Every http response contains http response headers and body.

What does HttpClient post return Angular?

HttpClient. post() method is an asynchronous method that performs an HTTP post request in Angular applications and returns an Observable. HttpClient. post() has a type parameter similar to the HttpClient. get() request, through which we can specify the expected type of the data from the server.


2 Answers

Create a HttpInterceptor:

@Injectable()
export class CustomInterceptor implements HttpInterceptor { 
    
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        request = request.clone({
            withCredentials: true
        });
    
        return next.handle(request);
    }
}

@NgModule({
    bootstrap: [AppComponent],
    imports: [...],
    providers: [
      {
        provide: HTTP_INTERCEPTORS,
        useClass: CustomInterceptor ,
        multi: true
      }
    ]
})
export class AppModule {}
like image 111
Sachila Ranawaka Avatar answered Sep 26 '22 22:09

Sachila Ranawaka


You have two option here -

  1. HttpInterceptor

auth.service.ts

If you are writing any standard application which require credential validation now or later then you will need AuthService. However you can ignore right now if you want.

    // src/app/auth/auth.service.ts
    import { Injectable } from '@angular/core';
    import decode from 'jwt-decode';
    @Injectable()
    export class AuthService {
      public getToken(): string {
        return localStorage.getItem('token');
      }
      public isAuthenticated(): boolean {
        // get the token
        const token = this.getToken();
        // return a boolean reflecting 
        // whether or not the token is expired
        return tokenNotExpired(null, token);
      }
    }

app.module.ts

Provide HTTP_INTERCEPTORS which will intercept all request of yours.

       // src/app/app.module.ts
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    import { TokenInterceptor } from './../auth/token.interceptor';
    @NgModule({
      bootstrap: [AppComponent],
      imports: [...],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: TokenInterceptor,
          multi: true
        }
      ]
    })
    export class AppModule {}

token.interceptor.ts

This is Interceptor through which each HTTP request will pass through.

    // src/app/auth/token.interceptor.ts
    import { Injectable } from '@angular/core';
    import {
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpInterceptor
    } from '@angular/common/http';
    import { AuthService } from './auth/auth.service';
    import { Observable } from 'rxjs/Observable';
    @Injectable()
    export class TokenInterceptor implements HttpInterceptor {
      constructor(public auth: AuthService) {}
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        
        request = request.clone({
          setHeaders: {
            Authorization: `Bearer ${this.auth.getToken()}`
          }
        });
        return next.handle(request);
      }
    }
  1. Overwrite the standard HttpClient

app.module.ts

        @NgModule({
            providers: [ // expose our Services and Providers into Angular's dependency injection
                {provide: HttpClient, useClass: ExtendedHttpService},
            ]
        })
        export class AppModule {
    }

extended-http.service.ts

    import {Injectable, Injector} from '@angular/core';
    import {Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers} from '@angular/http';
    import {Observable} from 'rxjs/Observable';
    import {Router} from '@angular/router';
    import {AuthService} from './auth.service';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/observable/throw';
    
    @Injectable()
    export class ExtendedHttpService extends HttpClient {
        private router: Router;
        private authService: AuthService;
    
        constructor(backend: XHRBackend, defaultOptions: RequestOptions, private injector: Injector) {
            super(backend, defaultOptions);
    
        }
    
        request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    
            if (typeof url === 'string') {
                if (!options) {
                    options = {headers: new Headers()};
                }
                this.setHeaders(options);
            } else {
                this.setHeaders(url);
            }
            //console.log("url: " , url , ", Options:" , options);
            return super.request(url, options).catch(this.catchErrors());
        }
    
        private catchErrors() {
    
            return (res: Response) => {
                if (this.router == null) {
                    this.router = this.injector.get(Router);
                }
                if (res.status === 401 || res.status === 403) {
                    //handle authorization errors
                    //in this example I am navigating to login.
                    console.log("Error_Token_Expired: redirecting to login.");
                    this.authService.logout();
                }
                return Observable.throw(res);
            };
        }
    
        private setHeaders(objectToSetHeadersTo: Request | RequestOptionsArgs) {
    
            if (this.authService == null) {
                this.authService = this.injector.get(AuthService);
            }
            //add whatever header that you need to every request
            //in this example I could set the header token by using authService that I've created
            objectToSetHeadersTo.headers.set('Authorization', this.authService.getAuthToken());
        }
    }
like image 22
Sunil Singh Avatar answered Sep 22 '22 22:09

Sunil Singh