You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 18独立组件对接Azure AD遇NullInjectorError问题求助

问题:Angular 18独立组件对接Azure AD后登录界面无法显示,控制台抛出NullInjectorError

控制台错误信息:

main-G2LTX4LO.js:14 ERROR
NullInjectorError: NullInjectorError: No provider for n!
at Ru.get (main-G2LTX4LO.js:14:1135) at ec.get (main-G2LTX4LO.js:14:10733) at ec.get (main-G2LTX4LO.js:14:10733) at ec.get (main-G2LTX4LO.js:14:10733) at Rg.get (main-G2LTX4LO.js:14:63453) at Vw (main-G2LTX4LO.js:14:22071) at Bw (main-G2LTX4LO.js:14:22311) at K (main-G2LTX4LO.js:14:41655) at n.ɵfac [as factory] (main-G2LTX4LO.js:42:31311) at zo (main-G2LTX4LO.js:14:23511)

环境说明:使用Angular 18独立组件模式,未使用app.module

以下是相关配置代码:

app.config.ts

import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClient, provideHttpClient, withFetch } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { routes } from './app.routes';
import { OAuthModule, OAuthService } from 'angular-oauth2-oidc';

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    importProvidersFrom(
      BrowserAnimationsModule,
      OAuthModule.forRoot(),
      TranslateModule.forRoot({
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient]
        }
      })
    ),
    provideHttpClient(withFetch()),
    OAuthService
  ]
};

auth.config.ts

import { AuthConfig } from 'angular-oauth2-oidc';
 
export const authConfig: AuthConfig = {
 
  // 身份提供商地址
  issuer: 'secret',
 
  // 登录后重定向回SPA的URL
  redirectUri: window.location.origin + '/',
 
  // SPA在认证服务器注册的ID
  clientId: 'secret',
 
  // 客户端请求的权限范围
  // 前三个由OIDC定义,第四个是特定业务场景的权限
  //scope: 'openid your-app-id',
  
  // 或者使用API权限范围  
  scope: 'openid https://your-tenant.onmicrosoft.com/spa-app/read https://your-tenant.onmicrosoft.com/spa-app/write',

  strictDiscoveryDocumentValidation: false
}

login.component.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { NavbarService } from '../services/nav.service';
import { TranslationService } from '../services/translation.service';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';

// 导入带令牌验证的OAuth服务
import { OAuthService } from 'angular-oauth2-oidc';

// 导入配置模块
import { authConfig } from '../auth.config';

@Component({
  selector: 'app-login',
  standalone: true,
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  imports: [TranslateModule, HttpClientModule]
})
export class LoginComponent implements OnInit, OnDestroy {
  currentLang: string = 'es';

  constructor(
    private router: Router,
    private navbarService: NavbarService,
    private translationService: TranslationService,
    private oauthService: OAuthService 
  ) {
    this.currentLang = this.translationService.getCurrentLang();

    this.translationService.onLangChange().subscribe(event => {
      this.currentLang = event.lang;
    });

    this.oauthService.configure(authConfig);
    this.oauthService.setupAutomaticSilentRefresh();
    
    this.oauthService.loadDiscoveryDocument().then(() => {
      this.oauthService.tryLogin();
    });
  }

  ngOnInit() {
    this.navbarService.hideNavbar();
    this.navbarService.hideSidebar();
  }

  ngOnDestroy() {
    this.navbarService.displayNavbar();
  }

  usuarioFinal() {
    this.navbarService.displayNavbar();
    sessionStorage.setItem('selectedLang', this.currentLang);
    const consentimiento = sessionStorage.getItem('consentimiento');
    if (consentimiento === 'aceptado') {
      this.router.navigate(['/crear-sesion']);
    } else {
      this.router.navigate(['/consentimiento-informado']);
    }
  }

  switchLanguage(lang: string) {
    this.translationService.changeLang(lang);
  }

  getEspIcon(): string {
    return this.currentLang === 'es' ? 'assets/img/idioma_esp_on.svg' : 'assets/img/idioma_esp_off.svg';
  }

  getEngIcon(): string {
    return this.currentLang === 'en' ? 'assets/img/idioma_ingles_on.svg' : 'assets/img/idioma_ingles_off.svg';
  }

  public login() {
    this.oauthService.initImplicitFlow();
  }
}

内容的提问来源于stack exchange,提问作者Daniel Valverde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:17:05