我有一个组件,该组件是基于配置文件对象的用户名称。
模板的相应部分是:
<button mat-button [matMenuTriggerFor]="userMenu" *ngIf="isAuthenticated()">
{{profile?.name}}
</button>
,该配置文件已加载到该组件的ininit函数中:
ngOnInit() {
if (this.authService.userProfile) {
this.profile = this.authService.userProfile;
} else {
this.authService.getProfile((err, profile) => {
this.profile = profile;
});
}
}
当我第一次导航到此页面时,即使isAuthenticated
总是返回true
。
如果我刷新页面,它开始正确渲染。
我在做什么错?
之后,有些挖掘出来,看来它仅在身份验证后才发生。
这是Authservice代码:
import { Injectable } from '@angular/core';
import * as auth0 from 'auth0-js';
import { environment } from '../../../environments/environment';
import { Router } from '@angular/router';
@Injectable()
export class AuthService {
auth0 = new auth0.WebAuth(environment.auth0);
userProfile: any;
constructor(private router: Router) {
}
public login(): void {
this.auth0.authorize();
}
public handleAuthentication(): void {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
window.location.hash = '';
this.setSession(authResult);
this.router.navigate(['']);
} else if (err) {
this.router.navigate(['']);
console.log(err);
}
});
}
private setSession(authResult): void {
// Set the time that the Access Token will expire at
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('access_token', authResult.accessToken);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('expires_at', expiresAt);
}
public logout(): void {
// Remove tokens and expiry time from localStorage
localStorage.removeItem('access_token');
localStorage.removeItem('id_token');
localStorage.removeItem('expires_at');
// Go back to the home route
this.router.navigate(['']);
}
public isAuthenticated(): boolean {
// Check whether the current time is past the
// Access Token's expiry time
const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
return new Date().getTime() < expiresAt;
}
public getProfile(cb): void {
const accessToken = localStorage.getItem('access_token');
if (!accessToken) {
throw new Error('Access Token must exist to fetch profile');
}
const self = this;
this.auth0.client.userInfo(accessToken, (err, profile) => {
if (profile) {
self.userProfile = profile;
}
cb(err, profile);
});
}
}
显然,发生的事情是app-nav
首先在Auth-Callback中加载,而用户未首先记录。而且,由于每次路线更改时都不会重新加载组件,因此该组件没有获取有关登录用户的信息,因此它一直粘在这种情况下直到重新加载。
解决方案是甚至不在路由上包括导航组件,甚至不应该期望用户存在。