Я не мог решить это таким образом, но я мог решить это другим способом, вот как:
Ранее у меня был
- модуль tab1, модуль tab2, модуль tab3 ( профиль, логин, регистрация)
- Страница профиля охранялась AuthGuard. Если не было найдено ни одного пользователя, перенаправленного на логин, * из AuthGuard был вызван
- AuthService ->, укажите состояние пользователя как BehaviorObject -> см. Мой оригинальный вопрос
Это то, как я изменился
- модуль tab1, тот же модуль tab2
- модуль tab3 (страница профиля)
- вход в систему, регистрация в модуле root,
- , создан APP_INITIALIZER где я проверяю, есть ли пользователь в хранилище
- создал новый UserService просто для хранения пользователя
- AuthService просто управляет перенаправлениями, логином, регистрируется
-связанные коды
app.module.ts
-> в провайдерах
BootstrappingService,
{
provide: APP_INITIALIZER,
useFactory: (bootstrappingService: BootstrappingService) =>
() => bootstrappingService.initApp(),
deps: [BootstrappingService],
multi: true
},
BootstrappingService.ts
@Injectable()
export class BootstrappingService {
constructor(
private readonly storage: Storage,
private readonly platform: Platform,
private readonly userService: UserService
) {}
async initApp() {
await this.platform.ready();
const user: User = await this.storage.get(AuthService.STORAGE_KEY);
if (user) {
this.userService.user.next(user);
}
}
}
UserService.ts
-> удержание аутентифицированного (пользовательского) состояния
@Injectable({
providedIn: 'root'
})
export class UserService {
user: BehaviorSubject<User> = new BehaviorSubject(null);
constructor() { }
}
AuthService.ts
@Injectable({
providedIn: 'root'
})
export class AuthService {
static STORAGE_KEY = 'auth-user';
redirectUrl: string;
constructor(
@Inject(ROUTES_CONFIG)
private readonly ROUTES: AppRoutes,
private readonly router: Router,
private readonly storage: Storage,
private readonly userService: UserService,
private readonly http: HttpClient
) {}
login(credentials): Observable<any> {
const loginObservable = this.http.post(`http://localhost:3000/auth/login`, credentials);
loginObservable.subscribe(async (user: User) => {
await this.storage.set(AuthService.STORAGE_KEY, user);
this.userService.user.next(user);
this.router.navigateByUrl(this.redirectUrl || this.ROUTES.PROFILE);
});
return loginObservable;
}
async logout(): Promise<void> {
await this.storage.remove(AuthService.STORAGE_KEY);
this.userService.user.next(null);
this.router.navigateByUrl(this.ROUTES.HOME);
}
}
и, наконец, AuthGuard.ts
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
@Inject(ROUTES_CONFIG)
private readonly ROUTES: AppRoutes,
private readonly userService: UserService,
private readonly authService: AuthService,
private readonly router: Router
) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | Observable<boolean> | boolean {
let url: string = state.url;
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
return this.userService.user
.asObservable()
.pipe(
map((user: User) => {
if (user) {
console.log('authenticated');
return true;
}
console.error('Not authenticated, redirecting to login', user);
this.router.navigateByUrl(this.ROUTES.LOGIN);
return false;
})
)
}
}
Теперь моя защищенная третья вкладка, кажется, обрабатывает вход / выход из системы правильно изложить. Нажатие refre sh на защищенном маршруте работает также.