this.user не определен при извлечении данных из app.component в angular -oidc-client

#angular #openid-connect #oidc-client-js #oidc-client

#angular #OpenID-connect #oidc-client-js #oidc-client

Вопрос:

Я использую oidc-client.js в своем angular проекте.

Прямо сейчас пользователи могут входить и выходить из системы, и все работает нормально. единственная проблема заключается в том, что когда я хочу вызвать службу в app.component, в перехватчике пользователь не аутентифицируется.

auth.service является :

     Injectable({
  providedIn: 'root'
})
export class AuthService extends BaseService {


  private _authNavStatusSource = new BehaviorSubject<boolean>(false);

  authNavStatus$ = this._authNavStatusSource.asObservable();

  private manager = new UserManager(getClientSettings());
  private user: User | null;


  constructor(private http: HttpClient) {
    super();   
    this.manager.getUser().then(user => {
      this.user = user;
      this._authNavStatusSource.next(this.isAuthenticated());
    });
  }

  login() {
    return this.manager.signinRedirect();
  }

  async completeAuthentication() {
    this.user = await this.manager.signinRedirectCallback();
    this._authNavStatusSource.next(this.isAuthenticated());
  }


  isAuthenticated(): boolean {
    return this.user != null amp;amp; !this.user.expired;
  }

  get authorizationHeaderValue(): string {
    return `${this.user.token_type} ${this.user.access_token}`;
  }

  async signout() {
    await this.manager.signoutRedirect();
  }
}

export function getClientSettings(): UserManagerSettings {
  return {
    authority:environment.authApiURI,
    client_id: 'medilloxdashboard',
    redirect_uri: environment.redirect_uri,
    post_logout_redirect_uri: environment.postLogoutRedirectUri,
    response_type: "id_token token",
    scope: "openid spa profile",
    filterProtocolClaims: true,
    loadUserInfo: true,
    automaticSilentRenew: true,
    silent_redirect_uri:environment.silentRedirectUri,
    userStore: new WebStorageStateStore({ store: localStorage })
  };
}
  

и я написал перехватчик для добавления токена ко всем подобным запросам :

 @Injectable()
export class AuthInterceptor implements HttpInterceptor {
  private authorizationHeader = "Authorization";

  constructor(
    private authService: AuthService,
    private router: Router) { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      headers: request.headers.set(this.authorizationHeader, this.authService.authorizationHeaderValue)
    });
    return next.handle(request);
  }

}
  

AuthService и AuthInterceptor зарегистрированы в Core nodule .

В App.Compoentn я вызываю подобную службу, которая вызывает REST api

     export class AppComponent implements OnInit {

  title = 'myapp';
  version: string;

     constructor(
        private router: Router,
        private dashboardService: DashboardService) {
        this.version = environment.version;
      }
    
      ngOnInit(): void {
        this.dashboardService.getDashboards().subscribe();
      }
    }
  

когда происходит этот вызов, я получаю getDashboards failed: this.user is undefined
, но я вызываю именно эту службу в других компонентах, и она работает нормально.

компоненты, которые вызывают эту службу и получают результат, находятся в их модулях.

В чем проблема?

Ответ №1:

Попробуйте выполнить свой вызов внутри и ngAfterViewCheck вместо ngOnInit , потому что службы на данный момент еще не запущены. Будьте осторожны, это будет выполняться бесконечно. Вы можете продолжать выполнять вызов, пока пользователь не определен.

Комментарии:

1. В ngAfterViewChecked нем все в порядке, но этот код запускается всякий раз, когда я нажимаю на каждую кнопку. Есть ли лучший способ?

2. мой ответ ниже (новый ответ стека)

Ответ №2:

Чтобы ответить на ваш вопрос @osman Rahimi «В ngAfterViewChecked все в порядке, но этот код запускается всякий раз, когда я нажимаю на каждую кнопку. Есть ли лучший способ?»

Ответ :

   data: any;
  ngAfterViewChecked (): void {
    if(this.data === null || this.data === undefined) {
      this.dashboardService.getDashboards().subscribe(data => this.data = data);
    }
  }
  

Комментарии:

1. Я опубликовал новый ответ, пожалуйста, проверьте, все ли в порядке или нет

Ответ №3:

Я создал Initializer подобное

 import { AuthService } from "./auth-service";
export function AuthInitializer(auth: AuthService) { return () => auth.isAuthenticated() };
  

и зарегистрирован так в core.module

 providers: [

{
  provide: APP_INITIALIZER,
  useFactory: AuthInitializer,
  deps: [AuthService],
  multi: true
}]
  

это работает отлично.