Ошибка в автоматическом обновлении токена с учетной записью Google - PullRequest
0 голосов
/ 17 января 2019

В угловом веб-приложении CLI мне нужно аутентифицировать пользователей с помощью аккаунтов Google.

Я использую библиотеку angular_oauth_oidc для управления всеми задачами, связанными с oauth. Я настроил OAutService для автоматического тихого обновления. Я вижу в fiddler, что служба выполняет запрос на обновление токена, но ответом является ошибка.

Это запрос (без секретной информации) к accounts.google.com:

.
GET /o/oauth2/v2/auth?response_type=id_token%20token&client_id=[MY_CLIENT_ID]&state=[MY_STATE]&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fassets%2Fsilent-refresh.html&scope=openid%20profile%20email&nonce=[MY_NONCE]&prompt=none&id_token_hint=[MY TOKEN] HTTP/1.1

А это ответ:

HTTP/1.1 302 Found
Content-Type: application/binary
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Thu, 17 Jan 2019 15:49:21 GMT
Location: http://localhost:4200/assets/silent-refresh.html#state=[STATE]&error_subtype=access_denied&error=interaction_required

Согласно документации библиотеки и стандарту oidc, запрос имеет все обязательные параметры, но я не могу заставить его работать.

Удалось ли кому-нибудь автоматически обновить молчание с помощью учетных записей Google?

Спасибо

1 Ответ

0 голосов
/ 29 января 2019

У вас есть эта ошибка:

  • error_subtype=access_denied
  • error=interaction_required

Если вы включите это в ваше клиентское приложение, вы также должны увидеть это на консоли:

import { OAuthErrorEvent } from 'angular-oauth2-oidc';
// ...
// Wherever you set up the library, do this:
this.authService.events.subscribe(e => (e instanceof OAuthErrorEvent) ? console.error(e) : console.warn(e));

По сути, ошибки означают, что ваша IDS отказывается отправлять токен в приложение Angular до тех пор, пока пользователь не будет каким-либо образом взаимодействовать с IDS. Как правило, это означает (повторно) ввод вашего имени пользователя и / или пароля или предоставление какого-либо согласия.

На стороне клиента, когда это происходит, вы должны позвонить initImplicitFlow(). В моем репозитории я делаю это так:

return this.oauthService.loadDiscoveryDocument()
  .then(() => this.oauthService.tryLogin())
  .then(() => {
    if (this.oauthService.hasValidAccessToken()) {
      return Promise.resolve();
    }

    // 2. SILENT LOGIN:
    return this.oauthService.silentRefresh()
      .then(() => Promise.resolve())
      .catch(result => {
        // Subset of situations from https://openid.net/specs/openid-connect-core-1_0.html#AuthError
        // Only the ones where it's reasonably sure that sending the
        // user to the IdServer will help.
        const errorResponsesRequiringUserInteraction = [
          'interaction_required',
          'login_required',
          'account_selection_required',
          'consent_required',
        ];

        if (result
          && result.reason
          && errorResponsesRequiringUserInteraction.indexOf(result.reason.error) >= 0) {

          // Enable this to ALWAYS force a user to login.
          this.oauthService.initImplicitFlow();

          // Should be superfluous, user should be redirected to IDS already...
          return Promise.reject();
        }

        return Promise.reject(result);
      });
  });
...