Задать вопрос
@NeuraLink

Как дождаться ответа от сервера для RouteGuard?

Есть сервис IdentityService:
@Injectable({
  providedIn: 'root'
})
export class IdentityService {

  constructor(private _client: HttpClient) {
  }

  authenticate(): Observable<IProfile> {
    return this._client.get<IProfile>(`${environment.mvcUrl}/profile`, {
      withCredentials: true
    });
  }
}


Метод authenticate возвращает структуру IProfile вида :
export interface IProfile {
    id: string;
    displayName: string;
    username: string;
    email: string;
    isAuthenticated: boolean;
}


Состояние IProfile хранится в store ngrx.

Теперь к проблеме) :
В приложении есть роуты, которые требуют, чтобы isAuthenticated был равен true.
Есть некий AuthGuard, который цепляется к этим роутам, и вот какая логика находится в нем :
return _store.pipe(select(Selectors.profile)).pipe(
    tap(profile => {
      if (!profile.isAuthenticated) {
       window.location.href = `${environment.mvcUrl}/login?returnUrl=${currentUrl}`
      }
    }),
    map(x => x.isAuthenticated)
  )


Проблема в том, что в initialState у меня isAuthenticated стоит false:
const _initialState: IProfileState = {
    profile: { displayName: "", email: "", id: "", username: "", isAuthenticated: false },
    isLoading: false,
    isCached: false,
    error: null,
};

export const profileReducers = createReducer(_initialState,
    on(ProfileActions.failure, (state, action) => ({ ...state, isLoading: false, error: action.error })),
    on(ProfileActions.get, (state) => ({ ...state, isLoading: true })),
    on(ProfileActions.getSuccess, (state, action) => ({ ...state, profile: action.profile, isLoading: false, isCached: true }))
);


AuthGuard всегда возвращает false, а потом приходит ответ от сервера и store обновляется на isAuthenticated: true, но уже поздно.

а this._store.dispatch(Actions.get()); расположенный в OnInit методе root компонента не помогает.
Как мне сделать так, чтобы в AuthGuard'е я дождался ответа от сервера, который поменяет в сторе IsAuthenticated на true ?
switchMap может где нужно использовать? Я сам бэкендер и во фронте только недавно начал разбираться, все эти функциональные штуки и observabl'ы сводят меня с ума
  • Вопрос задан
  • 47 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
1. Проверка токена должна производиться до старта приложения - смотреть APP_INITIALIZER
2. В вашем стейте есть флаг isLoading - нужно смотреть на него, нет смысла читать профиль до того, как он загрузится.
Можно так же добавить флаг Loaded, чтоб понимать что профиль вообще загружался.
3. Не надо перенаправлять используя window.location.href. Гард сам всё умеет. Он ожидает от вас true если все ок, false если запрет, и UrlTree если надо перенаправить. Есть метод router.createUrlTree
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы