this.user 在 angular -oidc-client 中从 app.component 获取数据时未定义
this.user is undefined when fetch data from app.component in angular -oidc-client
我在我的 angular
项目中使用 oidc-client.js
。
现在用户可以登录和注销并且工作正常。唯一的问题是,当我想在 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);
}
}
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
但我在另一个组件中调用了这个服务,它工作正常。
components which call this service and get the result are in their
modules.
问题出在哪里?
尝试在内部拨打电话 ngAfterViewCheck
而不是 ngOnInit
因为此时服务尚未启动。小心会被无限执行。您可以继续拨打电话,而用户未定义。
回答你的问题 @osman Rahimi“在 ngAfterViewChecked 中没问题,但是每当我点击每个按钮时,这段代码 运行。有没有更好的方法? “
答案:
data: any;
ngAfterViewChecked (): void {
if(this.data === null || this.data === undefined) {
this.dashboardService.getDashboards().subscribe(data => this.data = data);
}
}
我创建了一个这样的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
}]
这是完美的工作。
我在我的 angular
项目中使用 oidc-client.js
。
现在用户可以登录和注销并且工作正常。唯一的问题是,当我想在 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);
}
}
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
但我在另一个组件中调用了这个服务,它工作正常。
components which call this service and get the result are in their modules.
问题出在哪里?
尝试在内部拨打电话 ngAfterViewCheck
而不是 ngOnInit
因为此时服务尚未启动。小心会被无限执行。您可以继续拨打电话,而用户未定义。
回答你的问题 @osman Rahimi“在 ngAfterViewChecked 中没问题,但是每当我点击每个按钮时,这段代码 运行。有没有更好的方法? “
答案:
data: any;
ngAfterViewChecked (): void {
if(this.data === null || this.data === undefined) {
this.dashboardService.getDashboards().subscribe(data => this.data = data);
}
}
我创建了一个这样的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
}]
这是完美的工作。