我的角度应用程序有问题。如果在登录后,我转到另一个网站并再次返回我的应用程序,我就会注销。
即使我只刷新页面,我也会被注销。
这是我的身份验证服务:
export class AuthService {
private isAuthenticated = false;
constructor(private router: Router, private db: AngularFirestore, private angularFireAuth: AngularFireAuth) {}
login(authData: AuthData) {
this.angularFireAuth.auth.signInWithEmailAndPassword(
authData.email,
authData.password
).then(result => {
this.loggedInSuccessfully();
})
.catch(error => {
console.log(error);
});
}
logout() {
this.loggedOutSuccessfully();
}
isAuth() {
return this.isAuthenticated;
}
private loggedInSuccessfully() {
this.isAuthenticated = true;
this.router.navigate(['']);
}
private loggedOutSuccessfully() {
this.angularFireAuth.auth.signOut();
this.router.navigate(['login']);
this.isAuthenticated = false;
}
}
。这是AuthGuard类:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.authService.isAuth()) {
return true;
}
else {
this.router.navigate(['login']);
return false;
}
}
}
只要用户没有明确注销,我怎样才能保持登录状态?
问题出在您的代码中,因为这是默认行为 变量isAuthenticated
初始化为 false,只有在显式调用login()
函数后才修改 我建议使用Replaysubject
数据类型在AuthGuard
和服务之间进行通信 下面是一个示例代码 使用此逻辑,您甚至可以将数据库读取排队,以防路由逻辑依赖于数据库中存储的用户级别
import { ReplaySubject } from 'rxjs'
import { take, tap, map } from 'rxjs/operators';
export class AuthService {
private isAuthenticated: ReplaySubject<boolean> = new ReplaySubject(1)
constructor(private router: Router, private db: AngularFirestore,
private angularFireAuth: AngularFireAuth) {
angularFireAuth.authState.subscribe(state => {
this.isAuthenticated.next(state)
})
}
login(authData: AuthData) {
this.angularFireAuth.auth.signInWithEmailAndPassword(
authData.email,
authData.password
).then(result => {
this.loggedInSuccessfully();
})
.catch(error => {
console.log(error);
});
}
logout() {
this.loggedOutSuccessfully();
}
/**
* This function will never return a value until the replay subject gets a value, which is assigned only when the auth state changes
*/
isAuth() {
return this.isAuthenticated.pipe(
take(1),
map(authState => !!authState),
tap(authenticated => {
if (!authenticated) {
return false;
}
else {
return true;
}
}), );
}
private loggedInSuccessfully() {
this.isAuthenticated.next(true)
this.router.navigate(['']);
}
private loggedOutSuccessfully() {
this.angularFireAuth.auth.signOut();
this.router.navigate(['login']);
this.isAuthenticated.next(false)
}}
您的防护可以保持不变