1

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 && !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);
  }

}

AuthServiceAuthInterceptorCore 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 但我在另一个组件中准确地调用了这个服务,它工作正常。

调用此服务并获得结果的组件位于它们的模块中。

问题出在哪里?

4

3 回答 3

1

尝试在内部拨打电话,ngAfterViewCheck而不是ngOnInit因为此时服务尚未启动。小心会被无限执行。您可以继续拨打电话,而用户未定义。

于 2020-10-29T12:40:56.683 回答
1

回答你的问题@osman Rahimi “在 ngAfterViewChecked 中没问题,但是只要我点击每个按钮,这段代码就会运行。有更好的方法吗?”

答案 :

  data: any;
  ngAfterViewChecked (): void {
    if(this.data === null || this.data === undefined) {
      this.dashboardService.getDashboards().subscribe(data => this.data = data);
    }
  }
于 2020-10-30T11:28:46.800 回答
0

我创建了一个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
}]

这是完美的工作。

于 2020-11-06T17:10:35.260 回答