Обновите Angle2 Service Boolean перед маршрутизацией после начальной загрузки

Я использую Angular2 с ASP.NET Core MVC, и управление ручной URL-навигацией работает нормально, сервер успешно загружает мой Home view с Angular2.

При аутентификации пользователя я устанавливаю переменную сеанса следующим образом:

HttpHelper.HttpContext.Session.SetString("isLoggedIn", true.ToString() );

Я хочу, чтобы после того, как пользователь в приложении, если он хочет загрузить определенный маршрут, вручную перейдя к нему, я хочу, чтобы моя служба вызывала мой ASP-контроллер, чтобы проверить, прошел ли пользователь проверку подлинности, так что моя защита позволяет маршрутизация. Вместо этого для защиты по умолчанию установлено значение false, и я, очевидно, перенаправлен на мою страницу входа.

Вот мой метод ASP Controller, который я хочу вызвать, чтобы обновить значение IsLoggedIn в моем auth.service:

[HttpGet]
public IActionResult IsConnectedState()
{
    if (!String.IsNullOrWhiteSpace(HttpHelper.HttpContext.Session.GetString("isLoggedIn")))
        return Ok(true);
    else
        return Ok(false);
}

так что мой AuthenticationGuard может вызывать AuthenticationService для обновления логического значения, управляющего состоянием аутентификации: EDIT: вставка всего кода auth.guard.ts для более ясного объяснения

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
    if (!this.authService.isLoggedIn) {
        this.authService.setupLoggedInState().subscribe(() => {
            alert("guard check : " + this.authService.isLoggedIn);
            });
        }
    }

    canActivate()
    {
        if (this.authService.isLoggedIn) {
            return true;
        }

        this.router.navigate(['/login']);
        return false;
    }
}

с помощью следующего кода, обновляющего логическое значение в моем auth.service:

setupLoggedInState() {
    alert("Setting Up");

    // Setting up the Http call 
    let lControllerAction: string = "/IsConnectedState";
    let lControllerFullURL: string = this.controllerURL + lControllerAction;
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    // Call my ASP Controller IsConnectedState() method
    return this.http.get(lControllerFullURL, options)
        .map((res: any) => {
            // Réponse reçue du WebService
            let data = res.json();
            alert(data);
            if (data == true) {
                this.isLoggedIn = true;
            }
        }
        ).catch(this.handleError);
}

Проблема возникает, когда я пытаюсь вручную загрузить защищенный маршрут, я перенаправляюсь на страницу входа в систему, прежде чем логическое значение в моем сервисе обновляется. Я не знаю, какое решение я могу настроить для решения этой проблемы...

Я пробовал звонить

if (!this.authService.isLoggedIn) {
    this.authService.setupLoggedInState().subscribe(() => { });
}
  • в моей гвардии конструктор
  • в моем сервисном конструкторе

Но он все еще не делает это в нужный момент. Мое лучшее предположение было бы управлять этим, когда я загружаю свой первый AppModule, но даже если это может быть подходящий момент, я не гарантирую, что мое логическое значение будет обновлено к тому времени, когда Angular2 закончит загрузку, и выполнение синхронного вызова Http кажется действительно плохое решение, потому что это заблокирует браузер... Любая идея будет очень полезна.

PS: сегодня я написал аналогичную статью, но она была связана с другой проблемой, поэтому я привожу ее сюда, чтобы избежать путаницы: Управление состоянием аутентификации пользователя при ручной навигации по URL

1 ответ

Решение

Призвание subscribe() не дает автоматически значение. Если это вызывает запрос к серверу, потребуется много времени, пока не придет ответ. Браузер продолжает выполнять ваш код, и когда в конечном итоге приходит ответ от сервера, обратный вызов передается subscribe(...) называется наблюдаемым. Вы должны заставить свой AuthGuard ожидать наблюдаемый или фактически маршрутизатор, возвращая наблюдаемое из canActivate() поэтому маршрутизатор может ждать, пока наблюдаемое не выдаст ответ.

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
  canActivate() {
    return this.authService.checkLoggedIn
    .map(loggedIn => {
      if(loggedIn) {
        return true;
      } else {
        this.router.navigate(['/login']); // not tried myself to navigate here
        return false;
      }
    });
  }
}


@Injectable()
class LoginService {
  constructor(private http:Http) {}

  checkLoggeIn() {
    return.http.get(someUrl).map(val => val.json());
  }
}

См. Как правильно передать результат сетевого вызова Angular 2 Http в RxJs 5? для получения более подробной информации о том, как кэшировать результаты HTTP-запросов.

Другие вопросы по тегам