How to store token in local storage and pass it as bearer in all api cals in Angular

This is my first time building a login where I get user data from an API call and I need some help with it.

So the Login “workflow” is like this (Ihope I described it good, if more clarification is required please leave a comment)…
User comes to my login page, he click on login button, the login button goes to an external url where he makes the actual login and is there logen in and comess back to my page with some JSON data (name, token, etc..) of this user and is then automatically redirected inside my app.

So what I want is then to save this token in local storage and send this token in every other API call inside the app.

So here is my authentication.service.ts:

  isLoggedIn = false;
  redirectUrl: string | null = null;

  constructor(
    private http: HttpClient,
  ) { }

  login(): Observable<User> {
    const params = new HttpParams().append('param', 'value');
    return this.http.get<User>(`${environment.apiUrl}azure` + location.search, {params}).pipe(
      tap(() => (this.isLoggedIn = true))
    );
  }

Here is my login.component.ts:

  user: User;
  paramsObject: any;
  isLoggedIn = false;

  ngOnInit() {
    this.route.queryParamMap.subscribe(
      (params) => {
        this.paramsObject = { ...params.keys, ...params };
        console.log(this.paramsObject);
        
        if(this.route.snapshot.queryParamMap.get('code')) {
          this.authService.login().subscribe(
            data => {
              this.user = data;
              console.log('Izpis userja: ', data);
              if(this.user.token.length > 0) {
                console.log('Token exist: ', this.user.token);
                this.isLoggedIn = true;
                this.router.navigate(['/dashboard']);
              } else {
                console.log('Token does not exist');
                this.router.navigate(['/login']);
                return;
              }
            }
          )
        }
      })
  }

And I want to protect the routes if the user is not logen in in my auth.guard.ts:

  const authService = inject(AuthenticationService);
  const router = inject(Router);

  if (authService.isLoggedIn) {
    return true;
  } else {
    return router.parseUrl('/login');
  }

Here is an API call for some data and I am wondering how do I pass this stored token in other services to API calls:
example of my API call from customer.service.ts where I want to get some customer notes. How do I pass this token here?

 getSingleCustomerNotes(id:number): Observable<CustomerNotes> {
    return this.httpClient.get<CustomerNotes>(`${environment.apiUrl}customer/${id}/notes`, {headers});
  }

1- create an auth.interceptor.ts file (you can place it in src folder)

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from './services/auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private auth: AuthService) {}

  intercept(
    req: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    if (req.headers.get('skip')) {
      req = req.clone({
        headers: req.headers.delete('skip'),
      });
      req = req.clone({
        setHeaders: {
          Accept: 'application/json',
          Authorization: `Bearer ${this.auth.getToken()}`,
          'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
          Pragma: 'no-cache',
          Expires: '0',
        },
      });
      return next.handle(req);
    }
    req = req.clone({
      setHeaders: {
        'Content-Type': 'application/json; charset=utf-8',
        Accept: 'application/json',
        Authorization: `Bearer ${this.auth.getToken()}`,
        'Cache-Control': 'no-cache',
        Pragma: 'no-cache',
        Expires: 'Sat, 01 Jan 2000 00:00:00 GMT',
      },
    });
    return next.handle(req);
  }
}

2- in app.module.ts
in providers array add AuthInterceptor

import { AuthInterceptor } from './auth.interceptor';
import {
  HttpClientModule,
  HTTP_INTERCEPTORS,
  HttpClient,
} from '@angular/common/http';

@NgModule({
  declarations: [],
  imports: [],
  providers: [{
        provide: HTTP_INTERCEPTORS,
        useClass: AuthInterceptor,
        multi: true,
      }],
      bootstrap: [AppComponent],
      entryComponents: [],
      exports: [],
})
export class AppModule {}

and finally in your services just call http service and call your api’s

  updateGamme(id, gamme) {
    return this.http.post(this.baseUrl + '/modifyGamme/' + id, gamme)
}

Leave a Comment