TekOnline

Solving Multiple Instance Issues with OIDC Authentication in Angular

Context

When migrating from angular-oidc to oidc-client-ts, we encountered an interesting challenge with popup authentication and state management. The migration itself was straightforward, but we discovered a subtle issue with service instantiation.

The Problem

While implementing popup authentication, we noticed inconsistent behavior with our user state management. The symptoms were:User state updates weren’t propagating consistentlyMultiple instances of the same service appearingBehaviorSubject observers receiving different valuesThe root cause? The popup window was creating its own instance of our AuthService, complete with its own BehaviorSubject for user state. This meant we had at least two instances:The main window’s AuthService instanceThe popup window’s AuthService instanceEven though our service was decorated with @Injectable({ providedIn: ‘root’ }), the popup window created its own Angular context, effectively bypassing Angular’s singleton service pattern.

The Solution

We separated our concerns by creating a dedicated UserStateService:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { User } from 'oidc-client-ts';

@Injectable({
  providedIn: 'root'
})
export class UserStateService {
  private userSubject = new BehaviorSubject<User | null>(null);

  constructor() {
    console.log('UserStateService constructed');
  }

  updateUser(user: User | null): void {
    console.log('UserStateService updating user:', user);
    this.userSubject.next(user);
  }

  getCurrentUser(): User | null {
    return this.userSubject.getValue();
  }

  get user$() {
    return this.userSubject.asObservable();
  }
} 

Key Learnings

  1. Popup windows create their own JavaScript context, including their own Angular service instances.
  2. State management should be separated from authentication logic. Using a dedicated state service provides a cleaner, more maintainable solution.
  3. NgZone ensures proper change detection when updating state

Conclusion

When working with popup-based authentication in Angular, be aware that service singletons aren’t truly singleton across different window contexts. By separating state management into its own service, we create a more robust and maintainable solution.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *