使用穿戴式裝置進行驗證

Wear OS 應用程式可在沒有隨附應用程式的情況下獨立執行,也就是說 Wear OS 應用程式在存取應用程式時需要自行管理驗證方式 從網際網路取得資料但是手錶的螢幕尺寸較小 輸入功能會限制 Wear OS 應用程式可使用的驗證選項。

本指南說明 Wear OS 應用程式的建議驗證方式,以及這些方式不適合應用程式用途時的替代做法。

如要進一步瞭解如何設計良好的登入體驗,請參閱登入使用者體驗指南

訪客模式

請勿採用一律要求驗證的做法,而是盡可能提供最多 讓使用者無需登入即可存取

使用者可能會發現並安裝您的 Wear 應用程式,而不使用行動裝置 應用程式,因此他們可能沒有帳戶,可能不知道其中有哪些功能 優惠。請確保訪客模式功能可正確展示應用程式的各項功能。

部分裝置的解鎖狀態可能會更長

在搭載 Wear OS 5 以上版本的支援裝置上,系統會偵測 使用者將裝置佩戴在手腕上。如果使用者將手腕關機 然後將裝置從手腕取下 裝置的解鎖時間超過預期。

如果您的應用程式需要更高層級的安全性,例如顯示時 可能的敏感或私人資料—請先檢查手腕偵測狀態 已啟用:

val wristDetectionEnabled =
        isWristDetectionAutoLockingEnabled(applicationContext)

如果此方法的傳回值為 false,請提示使用者登入 帳戶,但才會顯示使用者專屬內容。

建議的驗證方式

請用以下的驗證方法,讓 Wear OS 應用程式得以獨立執行以下作業: 取得使用者驗證憑證

使用資料層傳遞權杖

透過 Wearable Data Layer,手機隨附應用程式可以安全將驗證資料傳送到 Wear OS 應用程式。以訊息或資料項目形式傳送憑證。

這類驗證通常不需使用者採取任何動作,不過請您避免在不通知使用者要登入的情況下進行驗證。您可以使用簡潔且可關閉的畫面告知使用者,行動裝置正在轉移他們的帳戶。

重要事項:這種驗證方式僅限和 Android 配對的手錶使用,且須安裝對應的手機應用程式,因此您的 Wear 應用程式必須另外提供至少一種驗證方式。請為沒有對應手機應用程式的使用者,或是與 iOS 裝置配對的 Wear OS 裝置使用者,提供替代驗證方式。

透過手機應用程式使用資料層傳遞權杖,如以下範例所示:

val token = "..." // Auth token to transmit to the wearable device.
val dataClient: DataClient = Wearable.getDataClient(context)
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)

監聽手錶應用程式的資料變更事件,如以下範例所示:

val dataClient: DataClient = Wearable.getDataClient(context)
dataClient.addListener{ dataEvents ->
    dataEvents.forEach { event ->
        if (event.type == DataEvent.TYPE_CHANGED) {
            val dataItemPath = event.dataItem.uri.path ?: ""
            if (dataItemPath.startsWith("/auth")) {
                val token = DataMapItem.fromDataItem(event.dataItem).dataMap.getString("token")
                // Display interstitial screen to notify the user they are being signed in.
                // Then, store the token and use it in network requests.
            }
        }
    }
}

如果想進一步瞭解如何使用 Wearable Data Layer,請參閱「在 Wear OS 上傳送資料和進行同步處理」。

使用 OAuth 2.0

Wear OS 支援兩種 OAuth 2.0 流程,如後續章節所述:

  • 搭配 Proof Key for Code Exchange (PKCE) 使用 Authorization Code Grant (授權碼許可),如 RFC 7636 中定義
  • Device Authorization Grant (裝置授權許可),如 RFC 8628 中定義

注意:為確保應用程式不會在手錶進入微光模式時關閉,請在執行驗證程序的活動中,使用 AmbientModeSupport.attach 啟用「螢幕長亮」功能。如要進一步瞭解微光模式的最佳做法,請參閱「在 Wear 上讓應用程式持續顯示」。

Proof Key for Code Exchange (PKCE)

如果想有效利用 PKCE,請用 RemoteAuthClient

如要透過 Wear OS 應用程式對 OAuth 提供者執行驗證要求,請建立 OAuthRequest 物件。這個物件包含用於取得權杖的 OAuth 端點網址和 CodeChallenge 物件。下列程式碼範例說明如何建立驗證要求:

val request = OAuthRequest.Builder(this.applicationContext)
    .setAuthProviderUrl(Uri.parse("https://...."))
    .setClientId(clientId)
    .setCodeChallenge(codeChallenge)
    .build()

建構驗證要求後,使用 sendAuthorizationRequest() 方法將要求傳送至隨附應用程式︰

val client = RemoteAuthClient.create(this)
client.sendAuthorizationRequest(request,
    { command -> command?.run() },
    object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it and use it in network requests.
        }

        override fun onAuthorizationError(errorCode: Int) {
            // Handle error
        }
    }
)

這項要求會觸發對隨附應用程式的呼叫,在使用者的手機網路瀏覽器中顯示驗證 UI。Auth 2.0 提供者可以驗證使用者身分,並徵求使用者同意授予要求的權限。回應會傳送到自動產生的重新導向網址。

授權成功或失敗後,OAuth 2.0 伺服器會重新導向到要求中的指定網址。如果使用者核准了存取要求,回應內便會提供授權碼。如果使用者未核准要求,回應會包含錯誤訊息。

回應會以查詢字串的形式呈現,其範例如下:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

這個項目會載入頁面,將使用者導向至隨附應用程式,隨附應用程式會驗證回應網址,然後使用 onAuthorizationResponse API 將回應轉發給第三方手錶應用程式。

隨後,手錶應用程式即可使用授權碼交換存取權杖。

注意:建構 OAuthRequest 之後,存取 redirectUrl 即可找到重新導向網址。

裝置授權許可

使用「裝置授權許可」時,使用者會在另一台裝置上開啟驗證 URI。接著,驗證伺服器會要求使用者核准或拒絕要求。

如要簡化這項程序,可以使用 RemoteActivityHelper 在使用者的配對行動裝置上開啟網頁,如以下範例所示:

// Request access from the authorization server and receive Device Authorization Response.
val verificationUri = "..." // Extracted from the Device Authorization Response.
RemoteActivityHelper.startRemoteActivity(
    this,
    Intent(Intent.ACTION_VIEW)
        .addCategory(Intent.CATEGORY_BROWSABLE)
        .setData(Uri.parse(verificationUri)),
    null
)
// Poll the authorization server to find out if the user completed the user authorization
// step on their mobile device.

如果您使用 iOS 應用程式,請利用通用連結攔截應用程式意圖,不要使用瀏覽器驗證權杖。

其他驗證方式

Wear OS 支援其他登入方式,如下列章節所述。

Google 登入

Google 登入可讓使用者以現有 Google 帳戶登入。它提供了 提供最佳的使用者體驗,也能輕鬆提供支援,特別是如果您已經導入 並放在手持裝置應用程式中

採用上述建議的驗證方式後,Google 登入是下一個首選解決方案,因為這種做法也能在 iOS 上順利運作。下列 一節說明如何完成基本的 Google 登入整合作業。

必要條件

您必須先設定 Google API 控制台專案,並設定 Android Studio 專案。如需更多資訊 請參閱 開始將 Google 登入整合至 Android 應用程式

如果您使用 Google 登入的應用程式或網站 與後端伺服器通訊,還有兩項額外的必要條件:

  • 為 建立 OAuth 2.0 網頁應用程式用戶端 ID 您的後端伺服器這個用戶端 ID 和應用程式用戶端 ID 不同。如要 資訊,請參閱 啟用伺服器端存取權
  • 傳送使用者的 ID 權杖,在伺服器上安全識別目前登入的使用者身分 存取 HTTPS如要瞭解如何在後端伺服器上驗證使用者身分,請參閱 使用後端伺服器進行驗證

將 Google 登入整合至應用程式

請查看及實作下列步驟,詳情請參閱各節 即可將 Google 登入整合至 Wear OS 應用程式:

  1. 設定 Google 登入
  2. 新增 Google 登入按鈕
  3. 在登入按鈕 已感應

設定 Google 登入及建構 GoogleApiClient 物件

在登入活動的 onCreate() 方法中設定 Google 登入以提出要求 應用程式所需的使用者資料。然後,請使用以下程式碼建立 GoogleApiClient 物件: 存取 Google Sign-In API 和您指定的選項。這些步驟 如以下範例所示:

public class MyNewActivity extends AppCompatActivity {

    private static final int RC_SIGN_IN = 9001;

    private GoogleSignInClient mSignInClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        GoogleSignInOptions options =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .build();

        mSignInClient = GoogleSignIn.getClient(this, options);
    }
}

在應用程式中新增 Google 登入按鈕

如要新增 Google 登入按鈕,請完成下列步驟:

  1. 新增 SignInButton 套用至應用程式的版面配置:
  2.  <com.google.android.gms.common.SignInButton
     android:id="@+id/sign_in_button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />
    
  3. 在應用程式的 onCreate() 方法中註冊按鈕的 使用者輕觸後可透過 OnClickListener 登入:
  4. Kotlin

    findViewById<View>(R.id.sign_in_button).setOnClickListener(this)
    

    Java

    findViewById(R.id.sign_in_button).setOnClickListener(this);
    

建立登入意圖及啟動登入流程

處理 onCLick() 中的登入按鈕輕觸動作 方法是使用 getSignInIntent() 方法。接著使用 startActivityForResult() 方法,增加圍繞地圖邊緣的邊框間距。

Intent intent = mSignInClient.getSignInIntent();
startActivityForResult(intent, RC_SIGN_IN);

系統會提示使用者選取想登入的 Google 帳戶。如果您已要求範圍 除了個人資料、電子郵件和開放 ID,系統還會提示使用者 再複習一下,機構節點 是所有 Google Cloud Platform 資源的根節點

最後,在活動的 onActivityResult 方法時,使用 getSignInResultFromIntent。擷取登入結果後,您可以 您可以使用 isSuccess 方法,增加圍繞地圖邊緣的邊框間距。如果登入成功,您可以呼叫 getSignInAccount 方法,藉此取得 GoogleSignInAccount 物件,內含目前登入狀態的相關資訊 例如使用者名稱相關步驟如以下範例所示..

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        Auth.GoogleSignInApi.getSignInResultFromIntent(data)?.apply {
            if (isSuccess) {
                // Get account information.
                fullName = signInAccount?.displayName
                mGivenName = signInAccount?.givenName
                mFamilyName = signInAccount?.familyName
                mEmail = signInAccount?.email
            }
        }
    }
}

Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (signInResult.isSuccess()) {
            GoogleSignInAccount acct = signInResult.getSignInAccount();

            // Get account information.
            fullName = acct.getDisplayName();
            givenName = acct.getGivenName();
            familyName = acct.getFamilyName();
            email = acct.getEmail();
        }
    }
}

如要查看 Google 登入功能的實作範例應用程式,請參閱 GitHub 上的 Horologist Google 登入範例

自訂程式碼驗證

除了前述驗證方法之外,您還可以 要求使用者透過其他裝置進行驗證 並取得一組效期短暫的數字代碼。接著,使用者進入 藉此確認使用者的身分並收到驗證權杖。

這項驗證流程會使用應用程式的登入模組,或 手動將第三方驗證服務供應商的登入方式整合至應用程式的程式碼。 雖然這種驗證方法必須手動操作和多花一番工夫 也更加安全。如果您需要在獨立的 Wear OS 應用程式中提早進行驗證,可以使用此方法。

這項設定的驗證流程如下:

  1. 使用者在需要授權的 Wear OS 應用程式中執行某個動作。
  2. Wear OS 應用程式向使用者顯示驗證畫面並指示 使用者輸入特定網址提供的代碼。
  3. 使用者切換到行動裝置、平板電腦或電腦,然後開啟瀏覽器。 會前往 Wear OS 應用程式指定的網址並登入。
  4. 使用者會收到一組效期短暫的數字代碼,然後前往 Wear OS 應用程式輸入該代碼 透過 Wear OS 內附的鍵盤驗證畫面:

  5. 之後,你就可以使用先前輸入的代碼,證明這項資訊正確無誤 然後交換代碼,取得儲存於 Wear OS 裝置並受到保護的驗證權杖 以供驗證呼叫

注意:使用者產生的代碼必須為純數字,不得包含任何字母字元。

這個驗證流程如下圖所示: