Wear OS 可在沒有隨附應用程式的情況下獨立執行,表示 Wear OS 應用程式在存取網際網路資料時,需要自行管理驗證方式。但手錶的螢幕尺寸較小,輸入功能也較不完善,因此 Wear OS 應用程式能夠使用的驗證方式有限。
本指南說明 Wear OS 應用程式的建議驗證方法,以及這些方法不適合應用程式用途時的替代選項。
訪客模式
請勿採用一律要求驗證的做法,而是要讓使用者在不須登入的情況下盡可能使用更多功能。
使用者可能會在未使用行動應用程式的情況下,探索並安裝您的 Wear 應用程式,因此他們可能沒有帳戶,也可能不知道其中提供了哪些功能。確認訪客模式功能正確展示應用程式的各項功能。
推薦的驗證方法
請用以下的驗證方法,讓 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 流程,詳情請參閱以下各節:
注意:為了協助確保應用程式不會在手錶進入微光模式時關閉,請在執行驗證程序的活動中使用 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 專案,然後才能在 Wear OS 應用程式中整合 Google 登入。詳情請參閱「開始將 Google 登入整合至您的 Android 應用程式」。
如果您使用 Google 登入的應用程式或網站會與後端伺服器通訊,則需要另外兩項必要條件:- 為後端伺服器建立 OAuth 2.0 網頁應用程式用戶端 ID。這個用戶端 ID 和您的應用程式用戶端 ID 不同。詳情請參閱「啟用伺服器端存取權」。
- 請用 HTTPS 傳送使用者的 ID 權杖,以便在伺服器上安全識別目前登入的使用者身分。如果想瞭解如何在後端伺服器驗證使用者,請參閱「透過後端伺服器驗證」。
將 Google 登入整合至應用程式
如要將 Google 登入功能整合至 Wear OS 應用程式,請檢閱及實作下列各節中所述的詳細步驟:
設定 Google 登入並建立 GoogleApiClient 物件
請在登入活動的 onCreate()
方法內設定 Google 登入,使其要求應用程式所需的使用者資料。接下來,請用 Google Sign-In API 存取權和您指定的登入方式建立 GoogleApiClient
物件。步驟請參見下列範例︰
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 登入按鈕的步驟:- 將
SignInButton
加入應用程式的版面配置︰ -
在應用程式的
onCreate()
方法中註冊按鈕的OnClickListener
,使用者輕觸後即可登入:
<com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Kotlin
findViewById<View>(R.id.sign_in_button).setOnClickListener(this)
Java
findViewById(R.id.sign_in_button).setOnClickListener(this);
建立登入意圖及啟動登入流程
使用 getSignInIntent()
方法建立登入意圖,以處理 onCLick()
方法中的登入按鈕輕觸操作。然後使用 startActivityForResult()
方法啟動意圖。
Intent intent = mSignInClient.getSignInIntent(); startActivityForResult(intent, RC_SIGN_IN);
系統會提示使用者選擇想登入的 Google 帳戶。如果您要求取得個人資料、電子郵件、開啟 ID 以外的資源,則系統也會提示使用者授予這些資源的存取權。
最後,在活動的 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 的「Android Wear Google 登入範例」。
自訂程式碼驗證
除了前述驗證方式之外,您還可以要求使用者透過其他裝置 (例如手機或平板電腦) 進行驗證,並取得時效短暫的數字代碼。隨後,使用者只要在 Wear OS 裝置上輸入該代碼,即可確認自己的身分並收到驗證權杖。
這個驗證流程可以使用應用程式的登入模組,或者手動將第三方驗證服務供應商登入方式整合至應用程式的程式碼。雖然這種驗證方式必須手動操作和多花一番心力,但是也因此更加安全,如果您的獨立 Wear OS 應用程式需要提早進行驗證,便可使用此方式。
這項設定的驗證流程如下:
- 使用者在需要驗證的 Wear OS 應用程式上執行動作。
- Wear OS 應用程式會顯示驗證畫面,並指示使用者輸入來自特定網址的代碼。
- 使用者切換到行動裝置、平板電腦或電腦,然後開啟瀏覽器並前往 Wear OS 應用程式指定的網址進行登入。
- 使用者會收到一組時效短暫的數字代碼,然後使用 Wear OS 內建的鍵盤將此代碼輸入 Wear OS 應用程式驗證畫面:
- 之後,您便可以用這組輸入的代碼證明使用者身分無誤,然後用這組代碼交換儲存於 Wear OS 裝置上的驗證權杖,用於後續的驗證呼叫。
注意:使用者產生的程式碼必須為純數字,不得包含任何字母字元。
以下圖表說明了這套驗證流程:
