Search code examples
angularionic-frameworkauthorization

How do I import an Auth Service in to the environment.ts file and use the token


I have auth.service.ts file that fetchs the access token

auth.service.ts

  public async getAccessToken(): Promise<string | undefined> {
    await this.initialize();
    const res = await this.getAuthResult();
    this.bearerToken = res?.accessToken;
    return res?.accessToken;
  }

I have been able to import the auth token to other pages using

import { AuthService } from '../../services/auth/auth.service';

async getToken() {
  await this.auth.getAccessToken();
  console.log("token", this.auth.bearerToken);
}

What I am trying to do is import this token into the 'x-authorization-token' in the environment.ts file if possible

environment.ts

import { HttpHeaders } from '@angular/common/http';
import { AuthService } from '../app/services/auth/auth.service';

export const environment = { production: false };

export const headerAuth: any = {
  headers: new HttpHeaders({
    'x-authorization-token': '', // To be imported from Auth Service
    'access-control-allow-origin': 'https://XXXXX.fred.com/',
    'access-control-allow-methods': 'GET,POST,OPTIONS',
    'access-control-allow-headers': 'Content-Type, X-Authorization-Token, Origin',
    'content-type': 'application/json',
  })
}

Solution

  • I don't believe trying to get access to the token in the configuration file is the correct way to go. The dependency injection system isn't conveniently available and configuration shouldn't block your application startup. Instead, utilize the HttpInterceptor interface to add the header to requests made by your application.

    Since your service returns a Promise, you'll need to use something like the approach in this answer to handle the async/await aspect as an Observable instead.

    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpRequest,
    } from '@angular/common/http';
    import { inject, Injectable } from '@angular/core';
    import { from, lastValueFrom, Observable } from 'rxjs';
    import { AuthService } from './auth.service';
    
    @Injectable()
    export class AuthTokenHeaderInterceptor implements HttpInterceptor {
    
      private readonly authService = inject(AuthService);
    
      // If you're in Angular 13 or below, use the constructor
      // instead of the inject() method:
      // constructor(private readonly authService: AuthService) {}
    
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        return from(this.handle(request, next));
      }
    
      async handle(request: HttpRequest<any>, next: HttpHandler) {
        const token = await this.authService.getAccessToken();
        const newRequest = request.clone({
          setHeaders: {
            'x-authorization-token': token,
          },
        });
        return await lastValueFrom(next.handle(newRequest));
      }
    }
    

    Make sure to add the interceptor to your dependency injection tree in your NgModule.providers array or ApplicationConfiguration.providers array depending on whether your application is module-based or standalone.

    providers: [
      { 
        provide: HTTP_INTERCEPTORS, 
        useClass: AuthTokenHeaderInterceptor, 
        multi: true 
      }
    ]