Angular SPA с сервером идентификации и oidc-client-js: есть ли шаблон для запуска входа в систему при запуске приложения (без использования кнопки входа в систему)?

Я работаю с угловым 8 SPA, и я пытаюсь использовать oidc-client- js для аутентификации пользователей. Провайдер идентификации реализуется с помощью сервера идентификации 4.

Наш желаемый пользовательский опыт заключается в следующем: когда SPA загружается в браузере, не требуя какого-либо взаимодействия с пользователем, запускается процесс входа в систему. Другими словами, мы хотели бы запускать процесс входа в систему автоматически и избежать необходимости в явной кнопке входа в систему в первом представлении приложения.

AppComponent - это первый компонент, загруженный в наше приложение, и он имеет следующий метод инициализации:

ngOnInit() {
    this.authService.login();
  }

Вход в службу аутентификации выполняет следующие действия:

login() {
        return this.userManager.signinRedirect();
    }

Таким образом мы можем успешно перенаправить пользователя на форму входа на сервер идентификации. После отправки формы входа в систему сервер идентификации перенаправляет пользователя обратно в приложение SPA по настроенному uri перенаправления (/signin-callback).

На этом этапе мы хотели бы загрузить компонент, способный завершить процесс входа. Этот компонент должен вызывать следующий метод службы аутентификации внутри своего ngOnInit метода:

completeLogin() {
        return this.userManager.signinRedirectCallback().then(user => {
          console.log("Login has been completed.", user);
          return user;
        });
    }

К сожалению, этот подход не работает, потому что, когда сервер идентификации перенаправляет обратно в приложение SPA (после отправки формы входа), AppComponent загружается в браузер, и процесс входа в систему запускается один раз снова, и начинается бесконечный цикл перенаправления, пока браузер, наконец, не взорвется.

Есть ли у нас способ заставить эту работу работать?

Дополнительные замечания:

  • во всех найденных мной примерах используется явная кнопка входа в систему, поэтому я спрашиваю себя, имеет ли вообще смысл наше желаемое поведение
  • основная проблема в том, что мы всегда вызываем this.userManager.signinRedirect() при загрузке приложения в браузере; мы должны найти способ избежать вызова, если поток входа уже запущен и приложение загружается из-за перенаправления после того, как пользователь входит в систему на уровне сервера идентификации. Есть ли надежный способ сделать это?

Обновление от 15 сентября 2020 г.

Самый простой способ, который я нашел для решения этой проблемы, - это выполнение обратного вызова перенаправления sigin внутри статической HTML-страницы, которая не является частью приложения angular. Вы можете найти пример в папке с образцами клиента js oidc. репозиторий


person Enrico Massone    schedule 10.09.2020    source источник


Ответы (2)


ТРЕБОВАНИЯ

Есть два основных аспекта в выполнении этой работы. На самом деле это шаблон проектирования, который может быть реализован на любом языке:

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

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

МОЙНЫЕ РЕСУРСЫ

В приведенном ниже коде используется простой Typescript, и вам нужно будет перевести его в предпочтительный синтаксис Angular.

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

person Gary Archer    schedule 10.09.2020

В вашем auth.service у вас, вероятно, есть что-то вроде этих двух функций:

private checkUser = (user : User): boolean => {
    return !!user && !user.expired;
}

public isAuthenticated = (): Promise<boolean> => {
    return this._userManager.getUser()
    .then(user => {
      if(this._user !== user){
        this._loginChangedSubject.next(this.checkUser(user));
      }

      this._user = user;

      return this.checkUser(user);
    })
}

Тогда вместо звонка

ngOnInit() {
    this.authService.login();
}

Вы можете использовать это:

ngOnInit() {
    this.authService.isAuthenticated().then((isAuthenticated) => {
    if (!isAuthenticated) {
        this.authService.login();
    }
});
}
person Adishone    schedule 15.02.2021