[英]Why my object become empty when I reach a specific route?
I have a problem.我有个问题。 So, I want to create a route guard in Angular that doesn't allow the user to reach login page if he is logged in. I check if he is logged in if the BehaviourSubject from the AuthService emits a new user object, but when I type in the search bar the URL of the login page, the user object emitted by the subject become empty.
所以,我想在 Angular 中创建一个路由守卫,如果他登录,则不允许用户访问登录页面。如果 AuthService 的 BehaviourSubject 发出一个新的用户对象,我检查他是否登录,但是当我在搜索栏中输入登录页面的URL,主体发出的用户对象变为空。 Do you know why is this happening?
你知道为什么会这样吗?
@Injectable({
providedIn: 'root'
})
export class LoggedInGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router){}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.authService.user$.pipe(map(user => {
// check if the user object is empty
const isAuth = !(!!Object.keys(user).length);
console.log(isAuth)
if(isAuth) {
return true;
}
// navigate to /books if user is logged in
return this.router.createUrlTree(['/books']);
}));
}
}
Here is my AuthService logic:这是我的 AuthService 逻辑:
export class AuthService {
private baseUsersUrl =
environment.firebase.databaseURL + MAIN_API_ENDPOINTS.users;
private userSource = new BehaviorSubject<User>(<User>{});
user$ = this.userSource.asObservable();
tokenExpirationTimer!: any;
constructor(private httpClient: HttpClient,private afAuth: AngularFireAuth, private router: Router) { }
login(email: string, password: string){
return this.httpClient.post<AuthResponseData>(MAIN_API_ENDPOINTS.login,{
email: email,
password: password,
returnSecureToken: true
}).pipe(
catchError(errorResponse => {
console.log(errorResponse);
let errorMessage = 'An unknown error occured!';
if(!errorResponse.error || !errorResponse.error.error) {
return throwError(errorMessage);
} else {
errorMessage = 'Email or password is incorrect'
}
return throwError(errorMessage);
}),
tap((resData) => {
this.saveUserData(email, resData.localId, resData.idToken, +resData.expiresIn);
}),
);
}
saveUserData(email: string, localId: string, idToken: string, expiresIn: number) {
const expirationDate = new Date(new Date().getTime() + expiresIn * 1000);
const currentUser: User = {
email,
id: localId,
token: idToken,
tokenExpirationDate: expirationDate
};
//token will expire in 1h
this.autoLogout(expiresIn * 1000);
document.cookie = 'token' + '=' + idToken;
}
autoLogin() {
const idToken = document.cookie.split('=')[1];
if(!idToken) {
return;
}
this.getUserData(idToken).subscribe((user) => {
this.saveUserData(user.users[0].email, user.users[0].localId, idToken, 100);
})
}
getUserData(idToken: string) {
return this.httpClient.post<any>(
MAIN_API_ENDPOINTS.userData,
{idToken: idToken});
}
And I added this route guard to the route this way:我以这种方式将此路线守卫添加到路线中:
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
canActivate: [LoggedInGuard]
}]
Whenever a route is typed in the search bar of the browser, the angular application bootstraps itself with a clean slate.每当在浏览器的搜索栏中输入一条路线时,angular 应用程序就会用干净的石板引导自己。 What you actually have to do is try to call the
autoLogin()
before your code reaches the LoggedInGuard
.您实际上需要做的是在您的代码到达
LoggedInGuard
之前尝试调用autoLogin()
。 Whenever a route is hit in an angular application, canActivate
is the first thing that runs, if present on the route.每当在 angular 应用程序中遇到一条路线时,
canActivate
是第一个运行的东西,如果路线上存在的话。 I believe your AuthService
runs after the LoggedInGuard
has finished performing its logic, due to which LoggedInGuard
fails to perform the Login Route Validation and let the route open.我相信您的
AuthService
在LoggedInGuard
完成其逻辑后运行,因此LoggedInGuard
无法执行登录路由验证并让路由打开。 If you want to try it, you can also try refreshing the browser window when you are on the login page.如果您想尝试,也可以尝试在登录页面时刷新浏览器窗口。 You will face the same scenario.
您将面临同样的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.