我有2个行为主题的authService:isLoggedIn和userLogedIn。 我在导航组件中订阅了它们。 登录时,我使用.next()方法向这两个主题发出新值。 检测到LoggedIn主题中的更改并更新了视图,但是未检测到userLogedIn中的更改,并且用户仍未定义。 当我重新加载整个页面时,用户现在已更新。
身份验证服务
import { Router } from '@angular/router';
import { StorageService } from './storage.service';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { tap } from 'rxjs/operators';
import { JwtHelperService } from '@auth0/angular-jwt';
import { BehaviorSubject, Observable } from 'rxjs';
import { User } from '../../components/users/models/user';
import { UserLoginDTO } from '../../components/users/models/user-login-dto';
import { UserRegisterDTO } from '../../components/users/models/user-register-dto';
@Injectable()
export class AuthService {
private readonly isLoggedInSubject$ = new BehaviorSubject<boolean>(
this.isUserLoggedIn()
);
private readonly loggedUserSubject$ = new BehaviorSubject<User>(
this.loggedUser()
);
constructor(
private readonly http: HttpClient,
private readonly storage: StorageService,
private readonly router: Router,
private readonly helper: JwtHelperService
) {
}
public get isLoggedIn$(): Observable<boolean> {
return this.isLoggedInSubject$.asObservable();
}
public get loggedUser$(): Observable<User> {
return this.loggedUserSubject$.asObservable();
}
public login(user: UserLoginDTO) {
return this.http
.post<{ token: string }>(`http://localhost:3000/session/login`, user)
.pipe(
tap(({ token }) => {
try {
const loggedUser = this.helper.decodeToken(token);
this.storage.save('token', token);
this.isLoggedInSubject$.next(true);
this.loggedUserSubject$.next(loggedUser);
} catch (error) {
}
})
);
}
public logout() {
this.storage.save('token', '');
this.isLoggedInSubject$.next(false);
this.loggedUserSubject$.next(null);
this.router.navigate(['homepage']);
}
public register(user: UserRegisterDTO) {
return this.http.post(`http://localhost:3000/api/users`, user);
}
private isUserLoggedIn(): boolean {
return !!this.storage.read('token');
}
private loggedUser(): User {
try {
return this.helper.decodeToken(this.storage.read('token'));
} catch (error) {
// in case of storage tampering
this.isLoggedInSubject$.next(false);
return null;
}
}
}
导航组件:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from '../../core/services/auth.service';
import { DialogService } from '../../core/services/dialog.service';
import { ConformationDialogBoxComponent } from '../../shared/conformation-dialog-box/conformation-dialog-box.component';
@Component({
selector: 'app-nav',
templateUrl: './nav.component.html',
styleUrls: ['./nav.component.css']
})
export class NavComponent implements OnInit, OnDestroy {
private loggedInSubscription: Subscription;
private userSubscription: Subscription;
public username: string;
public loggedIn = false;
public isAdmin = false;
public showAdminMenu = false;
constructor(
private readonly authService: AuthService,
private readonly dialog: DialogService
) {}
ngOnInit() {
this.userSubscription = this.authService.loggedUser$.subscribe(user => {
console.log(user);
this.isAdmin = user.isAdmin;
this.username = user.username;
});
this.loggedInSubscription = this.authService.isLoggedIn$.subscribe( res => {
console.log(res);
this.loggedIn = res;
});
}
ngOnDestroy() {
this.userSubscription.unsubscribe();
this.loggedInSubscription.unsubscribe();
}
public get profileLink() {
return ['/users', this.username];
}
public toggleAdminDropdown() {
this.showAdminMenu = !this.showAdminMenu;
}
public logout() {
const confirmData = {
description: 'Do you want to logout?',
function: this.authService.logout
};
const refDialog = this.dialog.openConfDialog(ConformationDialogBoxComponent,confirmData);
refDialog.afterClosed().subscribe(result => {
console.log(result);
if (result) {
this.authService.logout();
}
});
}
}
当我登录控制台时,我只会打印“ true”。而不是用户。