Angular 6 set withCredentials to true with every HttpClient call
Asked Answered
T

2

14

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?

Tyrontyrone answered 16/10, 2018 at 11:4 Comment(0)
H
30

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 {}
Heart answered 16/10, 2018 at 11:8 Comment(2)
const copiedReq = request.clone({withCredentials: true}); return next.handle(copiedReq) more clear.Gist
I'd call it requestCopy ;-)Nonconformity
B
4

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());
        }
    }
Buyer answered 16/10, 2018 at 11:16 Comment(1)
where's the missing parts of the AuthService?Uda

© 2022 - 2024 — McMap. All rights reserved.