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
相关产品推荐
相关产品推荐

