Application Not Loading Token from LocalStorage After Sign In But Works After Refresh

Viewed 110

I have an angular application and for some reason, the localstorage is showing the token from current User as null and therefore, the api return a 401 unauthorized. The issue happens after login and saving the token to localStorage and routes to the proper component to handle the next request. The request at this next page after login is returning 404 because the jwt did not find the token in the localstorage. Once I refresh the page, the api's start working again as if it found the token.

I have tried multiple approaches such as trying to inject localstorage, try async localstorage get, etc but nothing seems to work. Any help would be appreciated.

my JWT Interceptor is:

export class JwtInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available
      let currentUser = JSON.parse(localStorage.getItem('currentUser'));

      if (currentUser && currentUser.token) {
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${currentUser.token}`
                }
            });
        } 

      return next.handle(request);
    }
}

The authentication Code is t which I get and save to user is(the use of this function in the component is under this):

login(merchantId: string, client_id: string, code: string) {
    return this.http.post<any>(`${environment.apiUrl}/cloverApi/authenticate`, {merchantId: merchantId, client_id: client_id, code: code})
      .pipe(map(token => {
        // login successful if there's a jwt token in the response
        this.role = token.role;
        if (token && token.access_token) {
          // store user details and jwt token in local storage to keep user logged in between page refreshes
          this.setCookie('clover_access_token_cookie', 'Generic User', 364); //expires in 364 days as token only last 365
          console.log('in clover auth.service login completed. Cookie Stored under username: ' + this.getLoggedInSubject()); //*MES*
          return token;
        }
      }));
  }

So I get the clover api token and set it to the current user and send an update request as shown here:

this.cloverTokenService.login(this.url_merchant_id, this.url_client_id, this.url_code)
        .subscribe(
          data => {
            this.currentUser.cloverToken = data.access_token;
            this.currentUser.merchantId = this.url_merchant_id;
            this.userService.update(this.currentUser).subscribe((updatedUser:User)=> {
                localStorage.setItem('currentUser', JSON.stringify(this.currentUser));
                localStorage.setItem('', '');
                this.checkAuthAndRoute();
            },
              error => {
                console.error(error);
              })
          },
          error => {
            console.error(error);
          });
3 Answers

While setting your object in localStorage your token is under currentUser.cloverToken then when you retrieve it your trying to read currentUser.token

Either do this this.currentUser.token= data.access_token; or this Authorization: Bearer ${currentUser.cloverToken}

I believe you can make use of BehaviorSubject to pass token around as getting data from localstorage could have caused the issue somehow. You can next to the behavior subject when login succeeds and that can be used by the interceptor.

Note that you're using this.currentUser instead of the updatedUser inside the subscribe method.

And you are not setting this.currentUser.token anywhere in the snippets you provided. So, it's going to be undefined when you use it in your interceptor unless you are setting it somewhere else.

To confirm this, check your local storage from the browser. For example, in Chrome, it would be under the Application tab.

enter image description here

If currentUser appears there but doesn't have the token property then it's what I already mentioned.

If currentUser appears in the local storage with the token property, then you're probably not setting your interceptor correctly. In that case, you may find this article about interceptors helpful.

For example, I don't know if you omitted this on purpose but I don't see your interceptor annotated with the @Injectable() decorator.

Related