Is the Authorization Header in Angular JWT empty?

After following this tutorial, I set out to implement a login feature in my Angular app that communicates with a backend built on Spring Boot, utilizing Spring Security.

The issue at hand is clear: Somewhere within my code, the authorization header is not being properly added.

https://i.sstatic.net/jkZ60.png

In my jwt.interceptor.ts file, I have included some console.log commands to pinpoint where the problem lies:

@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  constructor(private authenticationService: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let currentUser = this.authenticationService.currentUserValue;
    console.log(currentUser);
    console.log(request.headers);
    if (currentUser) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${currentUser.token}` // mimicking what I do in Postman for access
        }
      });
    }
    return next.handle(request);
  }
}

Upon checking the console, it's odd that while the currentUser instance seems to contain a JWT token in its body, attempting to print out its token field (which is defined in the class) returns undefined.

https://i.sstatic.net/4v44R.png

Additionally, although an Authorization header is attached to the request, the value of Bearer turns out to be undefined.

https://i.sstatic.net/TUg2t.png

In my authorization service (authorization.service.ts), an object with the key currentUser is retrieved from local storage and its value is extracted. This information is stored upon logging in by taking a user from the /authenticate endpoint, stringify-ing it, and saving it in local storage. When accessing currentUserValue, I grab the .value field:

constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
}

.......

public get currentUserValue(): User {
    return this.currentUserSubject.value;
}

How can I ensure that the token is correctly added to my Authorization header?

I stumbled upon a workaround for this issue:

In the authentication.service, adjust the constructor as follows (and add the field to the class):

constructor(private httpClient: HttpClient) {
    this.tokenString = new BehaviorSubject<any>(JSON.parse(localStorage.getItem('currentUser'))).value.jwt;
}

Then, retrieve that field when setting the authorization header. While this solution resolves the immediate problem, I am open to better approaches.

Here's a more refined way to address this challenge:

Firstly, introduce a string field named jwt to your User class. Then, modify the constructor like so since currentUser can only be accessed once:

constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
    this.tokenString = this.currentUserSubject.value.jwt;
    this.currentUser = this.currentUserSubject.asObservable();
}

Answer №1

To implement this approach, ensure that the token is present in the jwt key within the console and access it via the token key.

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor(private authService: AuthenticationService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let user = this.authService.currentUserValue;
    console.log(user);
    console.log(req.headers);
    if (user) {
      // If a token exists for the user, add an 'Authorization' header with the JWT token to maintain access
      req = req.clone({
        setHeaders: {
          Authorization: `Bearer ${user.jwt}` // This mimics Postman behavior for authentication
        }
      });
    }
    return next.handle(req);
  }
}

Answer №2

According to the documentation, the correct key for setting headers is not setHeaders, but headers. Therefore, the proper way to clone a request and add authorization headers would be as follows:

request = request.clone({
  headers: new HttpHeaders({
    Authorization: `Bearer ${currentUser.token}`
  })
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A useful tip for adding an active class during navigation with router.navigate() in Angular

How can I add an active class based on the route when navigating to another route using router.navigate() Here is the template code: <div class="row"> <div class="col-lg-7"> <div class="row" *ngFor ...

Step-by-step guide to initializing data within a service during bootstrap in Angular2 version RC4

In this scenario, I have two services injected and I need to ensure that some data, like a base URL, is passed to the first service so that all subsequent services can access it. Below is my root component: export class AppCmp { constructor (private h ...

Update the fetch options type to include object as a valid body value

In the standard fetch() function, the BodyInit_ type restricts the assignment of objects to the body property. I am looking to create a custom wrapper for fetch that maintains the same signature as fetch, but allows the second argument (options) to includ ...

Angular - An intelligent access control manager that dynamically assigns roles and permissions based on class service functions

Is it possible to create a system where every user has a specific role or permission to access all menus, tabs, and actions in an Angular application, with the ability to show or hide the menu based on permissions? Here's my concept: 1. Implement a ...

Angular service not triggering timer

I've developed a timer service file in Angular for countdown functionality import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class TimerUtilService { initial_module_timer_value = 300; sec ...

Developing test cases for mat-autocomplete feature that customizes customer search

I am currently in the process of writing unit tests for an Angular app, specifically Angular6. One specific component that I am focusing on contains mat-autocomplete functionality. My goal is to ensure that the users are properly filtered based on the inpu ...

Transform angularjs directive into angular 10

After stumbling upon this intriguing code snippet, I decided to integrate it into my angular project: 'use strict'; /** * A mesmerizing floating text animation */ angular.module('g1b.text-animation', []). directive('textAnimatio ...

Having trouble implementing the latest Angular Library release

Just starting out with publishing Angular libraries, I've made my first attempt to publish a lib on NPM called wps-ng https://www.npmjs.com/package/wps-ng. You can check out my Public API file here https://github.com/singkara/wps-js-ng/blob/library_t ...

A declaration file for the 'vuelidate' module could not be located

When I was following the installation instructions for Vuelidate in Vuejs (), I encountered a warning message at this line: import Vuelidate from 'vuelidate' The warning states: There seems to be an issue with finding a declaration file for t ...

Guide to developing a dynamic method while utilizing IntelliSense assistance

When utilizing itemsApi in React reduxTool kit, dynamic functions like use..., mutate... are generated. These dynamically created methods possess complete intelligence as well. For instance, if you have createApi({... getItems: builder.query<any, st ...

Are there any code paths that do not result in a return value?

Can anyone provide insights on the error message "Not all code paths return the value" that I'm encountering? Additionally, is there a more efficient way to utilize ES6 features instead of using forEach loops? main.ts if (rxInfos.length && rxInfos ...

What is the most effective way to obtain JWT from a third-party provider?

Currently, I am delving into JWT and expressJS to expand my skillset. I have decided to create a simple JWT provider that I can utilize in all of my future personal projects. The concept behind my provider is straightforward. It will register with the Fac ...

Is there a ShadowDom issue causing display problems on Angular Elements when using Material Dialog?

Exploring the world of Angular Elements within Angular 7 has been an exciting journey for me. I have delved into creating lightweight web components that can seamlessly integrate into existing web pages with ease. Initial tests showed great promise, but I ...

Unable to narrow down the truthiness within nested functions: TypeScript issue

When analyzing the code in the shared playground (Playground Link), the compiler is showing an error indicating that Object is possibly 'null'. Could there be any scenario where the refresh function could be called, leading to a situation where ...

Tips on implementing django channels js_client with angular 2+

I have a quick question, how can I incorporate the JS client from Django Channels into my Angular 2+ application? You can find it at https://github.com/django/channels/tree/master/js_client. ...

Utilizing SVG Images on Buttons within Material Design (MD-Icon)

I have experimented with different methods, but none seem to be effective: <button md-icon-button color="primary"> <md-icon md-svg-src="./assets/img/sprites.svg">menu</md-icon> </button> and also tried this: <md-icon svgSrc= ...

Angular 8 fails to retain data upon page refresh

I have a property called "isAdmin" which is a boolean. It determines whether the user is logged in as an admin or a regular user. I'm using .net core 2.2 for the backend and Postgre for the database. Everything works fine, but when I refresh the page, ...

How can you create a scenario in Angular Material where items in a toolbar transition to the second line exclusively on mobile screens?

Visit the Angular Material website to see how the toolbar appears on a desktop: https://material.angular.io/ https://i.sstatic.net/KPFMv.png On mobile devices, the menu items Components, CDK, and Guides are displayed on the second line, while github, the ...

When clicking, clear the selected items and avoid the function from repeatedly executing

I am currently facing issues with implementing mat-select-autocomplete in my project. Firstly, I have noticed that the function's (selectionChange)="getSelectedOptions($event)" is triggered every time I click on mat-select-autocomplete. Is there a wa ...

Refresh the display after adding an item to an array in Angular

Currently, I am facing an issue with updating the view based on adding an item to an array of objects through a click handler. While the item is successfully pushed into the array, it does not reflect in the view. I am wondering if placing the method withi ...