Reputation: 1507
I am using oidc-client.js
in my angular
project.
Right now users could log-in and log out and it works fine. the only problem is that when I want to call a service in app.component, in the interceptor the user is not authenticated.
auth.service is :
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 })
};
}
and I wrote an interceptor to add token to all requests like this :
@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
and AuthInterceptor
are registered in Core nodule
.
In the App.Compoentn
I call a service like this which call a 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();
}
}
when this call happen, I get getDashboards failed: this.user is undefined
but I call exactly this service in another components and it works fine.
components which call this service and get the result are in their modules.
Where is the problem?
Upvotes: 1
Views: 896
Reputation: 1507
I created an Initializer
like this
import { AuthService } from "./auth-service";
export function AuthInitializer(auth: AuthService) { return () => auth.isAuthenticated() };
and registered like this in core.module
providers: [
{
provide: APP_INITIALIZER,
useFactory: AuthInitializer,
deps: [AuthService],
multi: true
}]
this is working perefectly.
Upvotes: 0
Reputation: 410
To answer to your question @osman Rahimi "In ngAfterViewChecked it is ok but this code run whenever I click on each butttons. Is there a better way?"
The answer :
data: any;
ngAfterViewChecked (): void {
if(this.data === null || this.data === undefined) {
this.dashboardService.getDashboards().subscribe(data => this.data = data);
}
}
Upvotes: 1
Reputation: 410
Try to make your call inside and ngAfterViewCheck
instead of ngOnInit
because services at this moment aren't initiated yet. Be careful that would be executed infinitely. You can keep make the call, while the user is undefined.
Upvotes: 1