Skip to content

Okta authState$ for Route resolving #137

@roddev-v

Description

@roddev-v

Describe the bug

Hi there! I encountered the following issue while working with OktaAuth and I wanted to identify a possible fix or bug to this scenario. This is my first time posting an issue on OSS! Sorry in advance for possible mistakes!

In my team we wanted to use okta-angular and the authState$ observable from the OktaAuthStateService inside a main Router resolver to load the user state and additional userProfile before the UI is rendered. Due to the nature of the Resolver we converted the authState$ to a Promise to handle state changes until the Route is resolved. The point is that we need to wait for an Authenticated state before loading content.

The issue is that the okta-angular wrapper over the @okta-auth-js package wraps the authStateManager in a BehaviorSubject that will resolve firstly an 'isAuthenticated: false' in stead of the original state (null). This approach causes a route resolving strategy to be complex to solve since implies multiple possible state changes. In my testing scenario I noticed aspects as:

const {authState$} = inject(OktaAuthStateService); authState$.console.log(state => console.log(state.isAuthenticated))

  • User not logged in: false -> false
  • User log-in with SSO (AD) provider: false -> true
  • User logged-in from previous session: false -> true
  • User logged-in with user/password: false -> false -> true
  • Redirect to callbackUrl -> One state update as false

Due to the unpredictable state changes a handler for the route get's very complicated to handle without hogging the route and assuming various strategies.

If this can be considered a bug, can the okta-angular package resolve in any way the actual auth state and not an initial isAuthenticated: false state and possible N other updates to the user auth state? I found this limitation in this specific resolving scenario where the data is needed before the page get's rendered.

I tried various operators to takeUntil the right state is emitted but this resolving issue makes the scenario of loading data before interaction complicated to handle.

Reproduction Steps?

  1. Create an Angular project and install @okta-angular
  2. On the main route of the application attach the following resolver:
export function oktaResolver: ResolveFn = () =>  {
  const oktaAuth = inject(OktaAuthStateService);
  
  return new Promise(resolve => {
  // values emitted: isAuthenticated: false / isAuthenticated: true
  // By the time I get the actual true state I already resolved the routing in order not to block the navigation
  // Would be awesome if the authState$ could resolve a single final state since the Angular resolver when it's server as a 
  // promise to await the route resolution will need a single value emitted.

    oktaAuth.authState$.subscribe(({isAuthenticated}) => {
      if(isAuthenticated) {
        // load extra user data;
        resolve();
      }
      resolve();
    })
  });
}
  1. Try a Redirect log-in and try to resolve the route without having to handle multiple state changes when the auth State get's updated

SDK Versions

@okta-angular 6.3.1
@okta-auth-js: 7.5.1

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions