Проблема входа в систему Ionic Okta для iOS - NSURLConnection code 1004 - PullRequest
0 голосов
/ 08 ноября 2018

Я сейчас пытаюсь развернуть приложение, которое использует ionic + okta. Я фактически начал с шаблона ionic + okta, который можно найти здесь: https://github.com/oktadeveloper/okta-ionic-auth-example

import { Component, ViewChild } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';
import { JwksValidationHandler, OAuthService } from 'angular-oauth2-oidc';
import * as OktaAuth from '@okta/okta-auth-js';
import { TabsPage } from '../tabs/tabs';

declare const window: any;

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html'
})
export class LoginPage {
  @ViewChild('email') email: any;
  private username: string;
  private password: string;
  private error: string;

  constructor(public navCtrl: NavController, private oauthService: OAuthService) {
    oauthService.redirectUri = 'http://localhost:8100';
    oauthService.clientId = '0oabqsotq17CoayEm0h7';
    oauthService.scope = 'openid profile email';
    oauthService.issuer = 'https://dev-158606.oktapreview.com/oauth2/default';
    oauthService.tokenValidationHandler = new JwksValidationHandler();

    // Load Discovery Document and then try to login the user
    this.oauthService.loadDiscoveryDocument().then(() => {
      this.oauthService.tryLogin();
    });
  }

  ionViewDidLoad(): void {
    setTimeout(() => {
      this.email.setFocus();
    }, 500);
  }

  login(): void {
    this.oauthService.createAndSaveNonce().then(nonce => {
      const authClient = new OktaAuth({
        clientId: this.oauthService.clientId,
        redirectUri: this.oauthService.redirectUri,
        url: 'https://dev-158606.oktapreview.com',
        issuer: 'default'
      });
      return authClient.signIn({
        username: this.username,
        password: this.password
      }).then((response) => {
        if (response.status === 'SUCCESS') {
          return authClient.token.getWithoutPrompt({
            nonce: nonce,
            responseType: ['id_token', 'token'],
            sessionToken: response.sessionToken,
            scopes: this.oauthService.scope.split(' ')
          })
            .then((tokens) => {
              const idToken = tokens[0].idToken;
              const accessToken = tokens[1].accessToken;
              const keyValuePair = `#id_token=${encodeURIComponent(idToken)}&access_token=${encodeURIComponent(accessToken)}`;
              this.oauthService.tryLogin({
                customHashFragment: keyValuePair,
                disableOAuth2StateCheck: true
              });
              this.navCtrl.push(TabsPage);
            });
        } else {
          throw new Error('We cannot handle the ' + response.status + ' status');
        }
      }).fail((error) => {
        console.error(error);
        this.error = error.message;
      });
    });
  }

  redirectLogin() {
    this.oktaLogin().then(success => {
      const idToken = success.id_token;
      const accessToken = success.access_token;
      const keyValuePair = `#id_token=${encodeURIComponent(idToken)}&access_token=${encodeURIComponent(accessToken)}`;
      this.oauthService.tryLogin({
        customHashFragment: keyValuePair,
        disableOAuth2StateCheck: true
      });
      this.navCtrl.push(TabsPage);
    }, (error) => {
      this.error = error;
    });
  }

  oktaLogin(): Promise<any> {
    return this.oauthService.createAndSaveNonce().then(nonce => {
      let state: string = Math.floor(Math.random() * 1000000000).toString();
      if (window.crypto) {
        const array = new Uint32Array(1);
        window.crypto.getRandomValues(array);
        state = array.join().toString();
      }
      return new Promise((resolve, reject) => {
        const oauthUrl = this.buildOAuthUrl(state, nonce);
        const browser = window.cordova.InAppBrowser.open(oauthUrl, '_blank',
          'location=no,clearsessioncache=yes,clearcache=yes');
        browser.addEventListener('loadstart', (event) => {
          if ((event.url).indexOf('http://localhost:8100') === 0) {
            browser.removeEventListener('exit', () => {});
            browser.close();
            const responseParameters = ((event.url).split('#')[1]).split('&');
            const parsedResponse = {};
            for (let i = 0; i < responseParameters.length; i++) {
              parsedResponse[responseParameters[i].split('=')[0]] =
                responseParameters[i].split('=')[1];
            }
            const defaultError = 'Problem authenticating with Okta';
            if (parsedResponse['state'] !== state) {
              reject(defaultError);
            } else if (parsedResponse['access_token'] !== undefined &&
              parsedResponse['access_token'] !== null) {

              resolve(parsedResponse);
            } else {
              reject(defaultError);
            }
          }
        });
        browser.addEventListener('exit', function (event) {
          reject('The Okta sign in flow was canceled');
        });
      });
    });
  }

  buildOAuthUrl(state, nonce): string {
    return this.oauthService.issuer + '/v1/authorize?' +
      'client_id=' + this.oauthService.clientId + '&' +
      'redirect_uri=' + this.oauthService.redirectUri + '&' +
      'response_type=id_token%20token&' +
      'scope=' + encodeURI(this.oauthService.scope) + '&' +
      'state=' + state + '&nonce=' + nonce;
  }
}

Я могу собрать приложение, используя ionic cordova build ios, и загрузить его в xcode. Он правильно подписан и загружается на мой телефон. Я могу перейти на страницу входа в okta, но когда я пытаюсь войти в систему, я перенаправляюсь обратно на страницу входа и получаю следующие ошибки в xcode:

API error: returned 0 width
nw_socket_connect connectx SAE_ASSOCID_ANY 0, Null, 0, Null, failed
connectx failed
TIC TCP Conn Failed Err(61)
NSURLConnection finished with error - code 1004
webView:didFailLoadWithError - -1004: Could not connect to the server
ERROR: ERROR Error: Uncaught (in promise): Error: Parameter jwks expected!
ValidateSignature@http://localhost...
ProcessIdToken@http://localhost...
...

Я не изменил код входа, кроме как использовать setRoot против push для успешного перенаправления. Приложение работает, когда я запускаю его в браузере или в ионной лаборатории. Я заметил, что исходный код использует localhost в качестве URL-адреса события. Я предполагаю, что это адрес браузера Cordova - это нужно изменить?

Я чувствую, что это настройка в xcode. Я пытаюсь собрать для iOS9 с xcode10.

...