構建具備用戶身份認證的 Ionic 應用

序言:本文主要介紹了使用 Ionic 和 Cordova 開發混合應用時如何添加用戶身份認證。教程簡易,對於 Ionic 入門學習有必定幫助。由於文章是去年發表,因此教程內關於 Okta 的一些使用步驟不太準確,可是經過 Okta 的官網也能夠找到對應的內容。另外,使用 npm 安裝 Ionic starter 模板可能會有安裝失敗的狀況,建議不要在這方面浪費太多時間,能夠直接在 Ionic 的 GitHub 倉庫 中下載 starter 模板。javascript

原文:How to Sprinkle ReactJS into an Existing Web Applicationcss

譯者:nzbinhtml

Banner

使用 Okta 和 OpenID Connect (OIDC),能夠很輕鬆的在 Ionic 應用中添加身份認證,徹底不須要本身實現。 OIDC 容許你直接使用 Okta Platform API 進行認證,本文的目的就是告訴你如何在一個 Ionic 應用中使用這些 API。我將演示如何使用 OIDC 重定向、Okta 的 Auth SDK 以及基於 Cordova 內嵌瀏覽器的 OAuth 進行登陸; 因爲功能還在開發中,因此省略了用戶註冊。java

爲何使用 Ionic?

Ionic 是一個用於開發原生及先進 web 應用的開源的移動端 SDK。它使用 Angular 和 Apache Cordova ,能夠用 HTML、CSS、和 JavaScript 來開發移動應用。Apache Cordova 將 HTML 代碼嵌入到一個設備上的原生 WebView 中, 經過外部功能接口來訪問原生資源。你可能據說過 PhoneGap —— 這是 Adobe Cordova 的商業版本。node

Cordova 和 PhoneGap 容許你使用一套代碼開發多個平臺的應用 (好比 Android 和 iOS) 。除此以外,應用程序和原生程序相差無盡而且和原生體驗同樣好。若是你須要開發原生功能,使用 web 技術是沒法實現的,可是有些原生插件能夠實現。 Ionic Native 是這些插件的精選集。android

我第一次使用 Ionic 是在 2013 年末。當時我作的項目是開發一款原生應用,可是打算使用 HTML 來開發適配多個屏幕的應用,這樣 web 開發者也能夠參與開發。我在 2014 年的三月寫了個人經歷。我喜歡使用 Ionic,我發現使用 Ionic 移植現有的應用程序更多的就是修改 HTML 和調整 CSS。ios

Ionic 2 在 一月份發佈, 可使用 Angular 開發 Ionic 應用。 Ionic 3 在 四月份發佈,容許使用 Angular 4 進行開發。git

注意: "Angular" 是 Angular 2+ 的通用名稱。AngularJS 是 1.x 版本的名稱。之因此用 Angular 命名是由於在 2017 年的三月發佈了 Angular 4 。能夠查看 Branding Guidelines for Angular and AngularJS 瞭解更多信息。angularjs

本文會演示如何建立一個簡單的 Ionic 應用以及如何添加用戶身份認證。大多數的應用都須要身份認證,這樣才能知道用戶是誰。一旦 app 知道你的身份,它就能夠保存你的信息及個性化的功能。github

開始使用 Ionic

爲了設置 Ionic 的開發環境,須要完成如下幾步:

  1. 安裝 Node.js
  2. 使用 npm 安裝 Ionic 和 Cordova: npm install -g cordova ionic

建立一個 Ionic 應用

在 terminal 窗口中,使用如下命令建立一個新的應用程序:

ionic start ionic-auth

命令行會提示選擇一個 starter 項目而且能夠選擇是否將應用鏈接到 Ionic Dashboard。對於本教程,選擇 tabs starter 項目,不須要將項目鏈接到 Ionic Dashboard。

相關教程:Getting Started with Angular v2+

項目建立須要花費一到兩分鐘,這取決於你的網絡鏈接速度。運行如下命令來打開你的 Ionic 應用。

cd ionic-auth
ionic serve

這個命令默認打開瀏覽器的 http://localhost:8100。你可使用 Chrome 的設備模式查看應用程序在 iPhone 6 中的效果。

Welcome to Ionic

使用 Ionic serve 命令的特色是它會在瀏覽器中顯示編譯錯誤,而不是(有時會隱藏)在開發控制檯。好比,給 app.component.ts 組件中的 rootPage 變量設置一個非法類型,你將看到如下錯誤。

Welcome to Ionic

添加用戶身份認證

Ionic Cloud 提供了免費的 Auth 服務。它容許使用郵箱及密碼驗證身份,也可使用社交提供商好比 Facebook、Google 和 Twitter 登陸。你可使用 @ionic/cloud-angular 依賴中提供的類建立身份認證。它也支持 自定義身份認證,可是 "須要你本身的服務器處理身份認證"。

目前尚未太多關於這方面的教程,不過從去年開始有了一些。

你可能注意到全部的教程都須要不少的代碼。另外,關於如何在後端的 Auth 服務中驗證用戶身份的文檔也很少。

在 Okta 中建立 OpenID Connect 應用

OpenID Connect (OIDC) 基於 OAuth 2.0 協議。它容許客戶端驗證用戶的身份並得到他們的基本配置文件信息。爲了將 Okta 的身份認證平臺整合到用戶身份認證中,須要如下步驟:

  • 註冊 並建立一個 OIDC 應用
  • 登陸 Okta 帳戶,而後導航到 Admin > Add Applications 並點擊 Create New App
  • 選擇 Single Page App (SPA) 以及 OpenID Connect 做爲登陸方式
  • 點擊 Create 並給你的應用起個名字 (好比 "Ionic OIDC")
  • 在下一頁上,添加 http://localhost:8100 做爲重定向的 URI 並點擊 Finish。你會看到如下設置信息:

Welcome to Ionic

  • 點擊 Assignments 標籤,而後選擇 Assign > Assign to People
  • 給本身分配一個用戶,或者其它你受權的人。

建立登陸頁

爲了建立身份認證的登陸頁,先建立 src/pages/login.tssrc/pages/login.html。在 login.html中,添加一個具備 username 和 password 的表單。

<ion-header>
  <ion-navbar>
    <ion-title>
      Login
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <form #loginForm="ngForm" (ngSubmit)="login()" autocomplete="off">
    <ion-row>
      <ion-col>
        <ion-list inset>
          <ion-item>
            <ion-input placeholder="Email" name="username" id="loginField"
                       type="text" required [(ngModel)]="username" #email></ion-input>
          </ion-item>
          <ion-item>
            <ion-input placeholder="Password" name="password" id="passwordField"
                       type="password" required [(ngModel)]="password"></ion-input>
          </ion-item>
        </ion-list>
      </ion-col>
    </ion-row>
    <ion-row>
      <ion-col>
        <div *ngIf="error" class="alert alert-danger">{{error}}</div>
        <button ion-button class="submit-btn" full type="submit"
                [disabled]="!loginForm.form.valid">Login
        </button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

你能夠利用幾個開源庫來完成實際的身份驗證。第一個是 Manfred Steyer's angular-oauth2-oidc. 這個庫能夠很容易的與 identity tokens 和 access tokens 交互。第二個是 Okta Auth SDK。因爲 OIDC 和 OAuth 不是身份認證協議,因此這是使用 JavaScript 完成身份驗證所必需的,沒必要重定向到 Okta 。

使用 npm 安裝 angular-oauth2-oidc

npm install angular-oauth2-oidc  --save

Okta Auth SDK 目前不支持 TypeScript,能夠將如下代碼添加到 src/index.html底部。

<script src="https://ok1static.oktacdn.com/assets/js/sdk/okta-auth-js/1.5.0/OktaAuth.min.js"></script>

src/pages/login/login.ts 中, 添加 LoginPage 類的基本結構,在構造器函數中使用 OAuthService (來自於 angular-oauth2-oidc) 配置了 OIDC 的設置。 你須要使用 Okta OIDC 設置中的 Client ID 替換 "[client-id]" 以及你帳戶的當前 URI 替換 "[dev-id]"。

import { Component, ViewChild } from '@angular/core';
import { NavController } from 'ionic-angular';
import { OAuthService } from 'angular-oauth2-oidc';
declare const OktaAuth: any;

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

  constructor(private navCtrl: NavController, private oauthService: OAuthService) {
    oauthService.redirectUri = window.location.origin;
    oauthService.clientId = '[client-id]';
    oauthService.scope = 'openid profile email';
    oauthService.oidc = true;
    oauthService.issuer = 'https://dev-[dev-id].oktapreview.com';
  }

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

修改 src/app/app.component.ts 驗證用戶是否登陸。若是沒有,將 LoginPage 設置爲 rootPage。

import { OAuthService } from 'angular-oauth2-oidc';
import { LoginPage } from '../pages/login/login';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any = TabsPage;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen,
              oauthService: OAuthService) {
    if (oauthService.hasValidIdToken()) {
      this.rootPage = TabsPage;
    } else {
      this.rootPage = LoginPage;
    }

    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

更新 src/app/app.module.ts,在 declarationsentryComponents 中添加 LoginPage。你也要將 OAuthService 添加到 providers 中。

@NgModule({
  declarations: [
    ...
    LoginPage
  ],
  ...
  entryComponents: [
    ...
    LoginPage
  ],
  providers: [
    OAuthService,
    ...
  ]
})

運行 ionic serve,確認 LoginPage在 app 首次加載後能夠展現出來。app 加載時會有如下報錯:

No provider for Http!

出現這個錯誤是由於 OAuthService 須要依賴 Angular 的 Http 模塊,可是尚未將該模塊導入到項目中。在 src/app/app.module.ts 中導入 HttpModule

import { HttpModule } from '@angular/http';

@NgModule({
  ...
  imports: [
    BrowserModule,
    HttpModule,
    IonicModule.forRoot(MyApp)
  ],
  ...
})

如今登陸頁已經展現出來了。你可使用 Chrome 的設備模式查看在 iPhone 6 上的效果。

Welcome to Ionic

爲了解決缺乏 TypeScript 支持的問題,你須要在 src/app/pages/login/login.ts 的頂部添加如下代碼。

declare const OktaAuth: any;

TIP: 要了解更多關於在 TypeScript 項目引用外部 JavaScript 庫的知識,能夠閱讀 Nic Raboy 寫的關於這方面的文章

src/app/pages/login/login.ts 中添加一個 login() 方法,它使用 Okta Auth SDK 進行: 1) 登陸; 2) 將 session token 轉換成 identity 和 access token。 一個 ID token 相似於身份證,它是標準的 JWT 格式,由 OpenID 提供者簽名。Access tokens 是 OAuth 規範的一部分。一個 access token 能夠是一個 JWT。它們用於訪問被保護的資源,一般是在發送請求時將它們添加到 Authentication 請求頭中。

login(): void {
  this.oauthService.createAndSaveNonce().then(nonce => {
    const authClient = new OktaAuth({
      clientId: this.oauthService.clientId,
      redirectUri: this.oauthService.redirectUri,
      url: this.oauthService.issuer
    });
    authClient.signIn({
      username: this.username,
      password: this.password
    }).then((response) => {
      if (response.status === 'SUCCESS') {
        authClient.token.getWithoutPrompt({
          nonce: nonce,
          responseType: ['id_token', 'token'],
          sessionToken: response.sessionToken,
          scopes: this.oauthService.scope.split(' ')
        })
          .then((tokens) => {
            // oauthService.processIdToken doesn't set an access token
            // set it manually so oauthService.authorizationHeader() works
            localStorage.setItem('access_token', tokens[1].accessToken);
            this.oauthService.processIdToken(tokens[0].idToken, tokens[1].accessToken);
            this.navCtrl.push(TabsPage);
          })
          .catch(error => console.error(error));
      } else {
        throw new Error('We cannot handle the ' + response.status + ' status');
      }
    }).fail((error) => {
      console.error(error);
      this.error = error.message;
    });
  });
}

經過 identity token 你能夠了解用戶的更多信息。經過 access token 你能夠訪問須要 Bearer token 的受保護的 API。好比, 在 在 Angular PWA 中添加身份認證中,有一個 BeerService ,它用於在發送 API 請求時攜帶 access token 。

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs';
import { OAuthService } from 'angular-oauth2-oidc';

@Injectable()
export class BeerService {

  constructor(private http: Http, private oauthService: OAuthService) {
  }

  getAll(): Observable<any> {
    const headers: Headers = new Headers();
    headers.append('Authorization', this.oauthService.authorizationHeader());

    let options = new RequestOptions({ headers: headers });

    return this.http.get('http://localhost:8080/good-beers', options)
      .map((response: Response) => response.json());
  }
}

您能夠(可選)在表單上方添加圖標來美化登陸頁。下載 這張圖片,將它拷貝到 src/assets/image/okta.png,在 login.html<form> 標籤中添加如下代碼。

<ion-row>
  <ion-col text-center>
    <img src="assets/image/okta.png" width="300">
  </ion-col>
</ion-row>

當你嘗試使用 Okta 的用戶證書登陸應用程序,你將在瀏覽器的控制檯看到跨域報錯。

XMLHttpRequest cannot load https://dev-158606.oktapreview.com/api/v1/authn. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.

爲了修復這一問題,在 Okta 修改 Trusted Origins (在 Security > API 下面), 將你的 client's URL 添加進去 (好比 http://localhost:8100)。檢查 CORS 和重定向的 origin 類型。

Welcome to Ionic

如今登陸能夠正常工做了,可是 UI 界面並無提示。在首頁的右上角添加一個 "Logout" 按鈕。用如下 HTML 替換 src/pages/home/home.html 中的 <ion-header>

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
    <ion-buttons end>
      <button ion-button (click)="logout()">
        Logout
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

src/pages/home/home.ts 中,添加一個 logout() 方法, 用於在 identity token 中獲取姓名及 claims 。ID token 中的 claims 是關於頒發者、用戶、目標受衆、過時時間及頒發時間的信息。你能夠閱讀 OIDC 規範中的標準 claims

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { LoginPage } from '../login/login';
import { OAuthService } from 'angular-oauth2-oidc';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController, public oauthService: OAuthService) {
  }

  logout() {
    this.oauthService.logOut();
    this.navCtrl.setRoot(LoginPage);
    this.navCtrl.popToRoot();
  }

  get givenName() {
    const claims = this.oauthService.getIdentityClaims();
    if (!claims) {
      return null;
    }
    return claims.name;
  }

  get claims() {
    return this.oauthService.getIdentityClaims();
  }
}

爲了在 home 標籤頁上展現信息,將如下 HTML 添加到 src/app/home/home.html 文件的第二段以後。

<div *ngIf="givenName">
  <hr>
  <p>You are logged in as: <b>{{ givenName }}</b></p>
  <div class="claims">
    <strong>Claims from Identity Token JWT:</strong>
    <pre>{{claims | json}}</pre>
  </div>
</div>

更新 src/app/home/home.scss,添加一些 CSS 讓原始的 JSON 看起來舒服一點。

page-home {
  .claims {
    pre {
      color: green;
    }
  }
  pre {
    border: 1px solid silver;
    background: #eee;
    padding: 10px;
  }
}

如今登陸以後你會看到你的姓名及聲明信息。

Home claims

你能夠退出以後看一下帶標識的登陸頁。

Login with logo

注意: 你可能注意到退出以後標籤頁並無消失。我正在查找 沒有正常工做 的緣由。

發佈到移動設備

使用 Ionic 在瀏覽器中開發移動應用是很是酷的事情。很高興你能看到本身的勞動成果以及優秀的手機應用。可是它的外觀和表現還不是原生應用。

爲了查看應用程序在不一樣設備上的效果,你能夠運行 ionic serve --lab--lab 標識會在瀏覽器中打開一個頁面讓你查看在不一樣設備中的效果。

Ionic labs

LoginPage 在加載時會自動聚焦到 email 輸入框。爲了自動激活鍵盤,你須要告訴 Cordova 沒有用戶交互的狀況下顯示鍵盤是能夠的。你能夠在根路徑的 config.xml 中添加如下代碼。

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

iOS

爲了模擬或者部署到 iOS 設備上,你須要一個 Mac 以及一個新安裝的 Xcode。若是你喜歡在 Windows 中建立 iOS 應用,Ionic 提供了一個 Ionic Package 服務。

確保打開 Xcode 完成安裝 ,而後運行 ionic cordova emulate ios 在模擬器中打開應用。

可能會提示你安裝 @ionic/cli-plugin-cordova 插件。當出現提示時輸入 "y",按回車。

TIP: 我發如今模擬器中運行應用程序時的最大問題是鍵盤很難彈出。爲了解決這一問題,當我須要在輸入框輸入文本時,我使用 Hardware > Keyboard > Toggle Software Keyboard

若是你在登陸頁輸入憑證,可能什麼也不會發生。打開 Safari 轉到 Develop > Simulator > MyApp / Login,你會看到控制檯有一條錯誤信息。若是你看不到開發菜單,從新執行 這篇文章 中的方法使其生效。

Web Inspector Error

若是打開 Network 標籤,你會看到只發送了一條請求 (to /authn),它和在瀏覽器中發送的兩條請求 (to /authn and /authorize) 有所不一樣。

DevTools Network Requests

我相信使用 Cordova 打包 app 以後並不會正常工做,由於經過內嵌的 iframe 向服務端發送請求,而後使用 postMessage 將結果返回當前窗口。Ionic/Cordova 彷佛並不支持這種方式。爲了解決這個問題,你可使用 Cordova 提供的 in-app 瀏覽器直接與 Okta 的 OAuth 服務通訊。Nic Raboy 演示了在 Facebook 中的操做方法,他在 Ionic 2 移動 App 中使用了 OAuth 2.0 服務

使用如下命令安裝 Cordova In-App Browser plugin

ionic cordova plugin add cordova-plugin-inappbrowser

打開 src/app/pages/login/login.html,用一個 <div> 包裹 <form>,爲了只在瀏覽器中運行時顯示登陸表單。添加一個新的 <div>,它會在模擬器或設備上運行時顯示。

<ion-content padding>
  <ion-row>
   <!-- optional logo -->
  </ion-row>
  <div showWhen="core">
    <form>
     ...
    </form>
  </div>
  <div hideWhen="core">
    <button ion-button full (click)="redirectLogin()">Login with Okta</button>
  </div>
</ion-content>

打開 src/pages/login/login.ts ,在 imports 下面添加一個 window 的引用。

declare const window: any;

爲了更容易的使用 OAuth 登陸,能夠添加如下方法。

redirectLogin() {
    this.oktaLogin().then(success => {
      localStorage.setItem('access_token', success.access_token);
      this.oauthService.processIdToken(success.id_token, success.access_token);
      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 + '/oauth2/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;
  }

把在構造器中設置的 redirectUri 替換成硬編碼 http://localhost:8100。若是省略這一步,當 app 在設備上運行時, window.location.origin 會跳轉到 file://。爲了將它設置成已知的 URL,咱們能夠經過 in-app browser 的 "loadstart" 事件查找它。

constructor(private navCtrl: NavController, private oauthService: OAuthService) {
  oauthService.redirectUri = 'http://localhost:8100';
  ...
}

更改以後,須要將 app 從新部署到手機上。

ionic cordova emulate ios

如今能夠點擊 "Login with Okta" 按鈕,而後輸入合法的憑證進行登陸。

Emulator Login Emulator Okta Login Emulator Home

使用這項技術的好處就是 Okta 的登陸頁具備「記住我」和「忘記密碼」的功能,因此不須要本身編寫代碼。

爲了將 app 部署到 iPhone,首先將手機插到電腦上。而後運行如下命令安裝 ios-deploy、構建 app 並在你的設備上運行。

npm install -g ios-deploy 
ionic cordova run ios

若是你以前沒有爲應用程序設置代碼簽名,則此命令可能會失敗。

Signing for "MyApp" requires a development team. Select a development team in the project editor.
Code signing is required for product type 'Application' in SDK 'iOS 10.3'

在 Xcode 中打開你的項目,運行如下命令。

open platforms/ios/MyApp.xcodeproj

Ionic's 開發文檔 有解決這一問題的說明。

選擇你的手機做爲 Xcode 的目標,而後點擊 play 按鈕運行 app。若是你是第一次作,Xcode 可能會加載一段時間,上方會顯示一條 "Processing symbol files" 的信息。

只要你已經設置了你的手機、電腦以及 Apple ID,你就能夠打開應用並登陸。如下是在個人手機上的展現效果。

iPhone Login iPhone Okta Login iPhone Home

Android

爲了模擬或者部署到 Android 設備上,你首先要安裝 Android Studio。在安裝過程當中,它會提示你將 Android SDK 安裝到哪裏。將這個路徑設置爲 ANDROID_HOME 的環境變量。在 Mac 上,it should be ~/Library/Android/sdk/

若是你已經安裝了Android Studio,請確保打開它以完成安裝。

爲了部署到 Android 模擬器,運行 ionic cordova emulate android。這個命令將安裝 Android 支持並打印關於如何建立模擬圖像的說明。

Error: No emulator images (avds) found.
1. Download desired System Image by running:
/Users/mraible/Library/Android/sdk/tools/android sdk
2. Create an AVD by running: /Users/mraible/Library/Android/sdk/tools/android avd
HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver

運行第一條建議並下載您想要的系統映像。而後運行第二個命令並用如下設置建立一個 AVD(Android 虛擬設備):

AVD Name: TestPhone
Device: Nexus 5
Target: Android 7.1.1
CPU/ABI: Google APIs Intel Axom (x86_64)
Skin: Skin with dynamic hardware controls

警告: 這些設置不適用於 Mac 上的 Android Studio 2.3.2 版本。當你嘗試運行第一條命令時,它會顯示如下內容:

*************************************************************************
The "android" command is deprecated.
For manual SDK, AVD, and project management, please use Android Studio.
For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager
*************************************************************************

爲了解決這個問題,打開 Android Studio,選擇 "Open an existing Android Studio project",而後選擇 ionic-auth/platforms/android 的路徑。若是提示升級,選擇 "OK",而後繼續建立一個新的 AVD ,和 Android Studio 文檔描述的那樣.

執行完這些步驟以後,你能夠運行 ionic cordova emulate android 查看運行在 AVD 中的 app。

Android Login Android Okta Login Android Home

注意: 若是應用程序顯示錯誤 "鏈接服務器失敗 (file:///android/www/index.html)",在 config.xml 中添加如下代碼。這行代碼將默認超時時間設置爲 60 秒 (默認 20)。感謝 Stack Overflow 社區 對此問題的解答。

<preference name="loadUrlTimeoutValue" value="60000"/>

使用 Ionic 開發 PWAs

Ionic 支持建立 progressive web apps (PWAs)。這意味着你能夠將 Ionic app 部署成 web app (不是移動端 app) ,它能夠在離線的 支持 service workers 的瀏覽器 中運行。

想要了解如何使用 service workers 並把 app 轉換成 PWA ,能夠閱讀 如何使用 Ionic 和 Spring Boot 開發移動應用PWAs 部分 。PWA 是能夠安裝在系統中的 web 應用程序。它能夠在離線狀況下工做,使用的是你最後一次與 app 交互的數據緩存。添加 PWA 功能可讓 app 加載更快,提供更好的用戶體驗。想要了解更多關於 PWA 的知識,能夠閱讀 The Ultimate Guide to Progressive Web Applications.

瞭解更多

我但願你喜歡這篇關於 Ionic、Angular 及 Okta 的教程。我喜歡 Ionic 是由於它能夠將你的 web 開發技能提高一個檔次,而且它能夠快速建立仿原生的移動應用。

你能夠在 GitHub 上查看本教程的完整代碼。若是你有問題,能夠經過 Twitter @mraible 或者在 Okta's Developer Forums 上聯繫我。

想要了解更多關於 Ionic、Angular 或者 Okta 的知識,能夠查看如下資源:

相關文章
相關標籤/搜索