getUser() fails immediately after the login redirection

Hi Guys,
I’m pretty new to the Okta SDK…
I’m trying to simply show the username once the user is logged in but i’m facing a strange behavior.
If I call getUser() immediately after the user login it fails saying:

AuthSdkError: getUserInfo requires an access token object

If i refresh the page, the getUser calls succeed and I get the username.
Here my code:

console.log('Started');

if (this.oktaAuth.isAuthenticated) {

  console.log('Autenicated');
  const userClaims = await this.oktaAuth.getUser();
  console.log('User');

  this.username = userClaims.name;
}
console.log('Finish');

As you can see once the login redirects to the app i get this error:

Once i refresh the page i get everything:

Any suggestion?

Thanks much!

Are you getting an Access Token for this user and storing it in the tokenManager when they sign in?

getUser() requires there to either be a token available in the tokenManager OR that you have passed the token object in as an argument, so if the accessToken is not available in the tokenManager, you will need to provide it when calling getUser

You can check if its available in the tokenManager by using tokenManager.get().

Thanks for the prompt reply!
I’m not able to retrieve the token because the tokenManager.get is a property which returns a promise but the object seems contain a token:

Code:

console.log(‘Started’);

if (this.oktaAuth.isAuthenticated) {

  console.log('Autenticated');
  const token = await this.oktaAuth.tokenManager.get;
  console.log(token.length);
  const userClaims = await this.oktaAuth.getUser();
  console.log('User');

  this.username = userClaims.name;
}
console.log('Finish');

Anyway, the if condition indicate that the user is authenticated, why is there no token?

Can you make sure that the token stored is an access token? It seems like the length is one, so its possible only an ID token is stored right now.

What OAuth flow are you using (Implicit or PKCE) and how/when are you storing the tokens in the token manager?

I’m using PKCE but I’m not requesting the token in any way, only using the code as explained on the official guide…

I agree with @andrea that you should check whether both tokens are present. If you open up the browser developer tools and check Local Storage, do you see both the idToken and accessToken in okta-token-storage?

The token seems there but I still receive the error:

Any suggestion?

Thanks much!

Any clue guys?
Thanks

Anybody can help here?
The error is systematic. I suppose the angular package has a bug in it…
In this way the OKTA authentication is not usable because i cannot authenticate the user in the first shot…

Any suggestion is very appreciated…

@lapo.martini Do you see the same behaviour when using the sample application? Does it occur across different browsers, or does the behavior vary based on what browser you are using?

I didn’t try the sample app, but my code is identical respect the documentation provided on OKTA website… on edge i have the same error plus an error on local storage always thrown by okta module which prevent to redirect to the authentication…

Where is getUser being called in your application? Is it on the same route that is handling the callback redirection?

If you try to pull the accessToken out of the token manager yourself, does that work or does it also fail?

Also what version of the AuthJS SDK are you using?

For Edge, you may want to try adding some polyfills, such as the ones that are available in AuthJS, to help alleviate that “Out of stack space” error.

I’m seeing this same behavior. In my configuration, the OktaAuthService is being configured into an Angular service. My theory is that the constructor for my service (which calls getUser) is being called before the login/callback endpoint has consumed the token on redirect. It does however defeat the purpose of having getUser return a promise if the promise can error out, rather than waiting for the result and returning a success.

I wrapped the entire getUser call in a subscription to authentication state, and the call seems to succeed now. It does require rather a lot of gyrations, and it would be better IMO if getUser would wait for the token to be populated (since it’s already a promise), perhaps with a timeout?

Here’s the updated code that does work for my service:
import { HttpClient } from ‘@angular/common/http’;
import { Injectable, OnInit, EventEmitter, Output } from ‘@angular/core’;
import { Observable } from ‘rxjs’;
import { environment as env } from “…/…/environments/environment”;
import { OktaAuthService } from ‘@okta/okta-angular’;

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {
  @Output()
  nameEmitter = new EventEmitter<String>();
  userName!: string;
  jwtError!: any;

  constructor(
    private authService: OktaAuthService
  ) {
    this.authService.$authenticationState.subscribe(
      {
        next: 
          authenticated => {
          if (authenticated) {
            this.authService.getUser()
            .then(it => {
                var name = it.name || "Guest";
                this.userName! = name;
                this.nameEmitter.emit(name);
              } 
            )
          }
        }
      }
    )
  }
}
                                Here the Solution is

I too got this exact issue and fixed the issuse in a certain amount of guesswork.The
okta-auth-js is the storage manager of jwt token.
In this issue, after refresh the page the getUser() call is succeed and can get the username. So I presummed that some time is needed as soon as login successful to get the call succeed . So, I fixed this issue by adding setTimeout() (note: setTimeout() time is user preference) in my code.

setTimeout(() => {
      this.oktaAuth.getUser().then(async (userData) => {
        this.userName = userData.name;
        this.isAuthenticated = await this.oktaAuth.isAuthenticated();
      });
    }, 400);

The number of setTimeout() code increases as getUser(0 call increases.So, add setTimeout() in the root component(app.component.ts) only once as following

setTimeout(() => {
// required code
    }, 400);

If any appropraite solution is there, please add it here.

Thanks a bunch!