Xác thực trên thiết bị đeo: Trình quản lý thông tin xác thực

Các ứng dụng Wear OS có thể chạy độc lập mà không cần có ứng dụng đồng hành. Tức là một ứng dụng Wear OS cần phải tự quản lý quy trình xác thực khi truy cập vào dữ liệu qua Internet. Nhưng kích thước màn hình nhỏ của đồng hồ và khả năng nhập liệu hạn chế làm giới hạn cách thức xác thực mà một ứng dụng Wear OS có thể sử dụng.

Hướng dẫn này cung cấp chỉ dẫn về phương thức xác thực được đề xuất cho các ứng dụng Wear OS, đó là Trình quản lý thông tin đăng nhập.

Để tìm hiểu thêm về cách thiết kế trải nghiệm đăng nhập tiện lợi, hãy xem Hướng dẫn về trải nghiệm người dùng đăng nhập.

Những điểm cần cân nhắc ban đầu

Trước khi bắt đầu triển khai, hãy cân nhắc những điểm sau.

Chế độ khách

Đừng yêu cầu xác thực cho mọi chức năng. Thay vào đó, hãy cung cấp cho người dùng nhiều tính năng nhất có thể mà không yêu cầu họ đăng nhập.

Có lẽ người dùng khám phá và cài đặt ứng dụng Wear của bạn mà không dùng ứng dụng di động. Vì vậy, họ có thể không có tài khoản và không biết những tính năng của ứng dụng đó. Hãy đảm bảo rằng chức năng của chế độ khách thể hiện chính xác các tính năng của ứng dụng.

Một số thiết bị có thể vẫn ở trạng thái mở khoá lâu hơn

Trên các thiết bị được hỗ trợ chạy Wear OS 5 trở lên, hệ thống sẽ phát hiện xem người dùng có đang đeo thiết bị trên cổ tay hay không. Nếu người dùng tắt tính năng phát hiện cổ tay rồi tháo thiết bị ra khỏi cổ tay, thì hệ thống sẽ giữ thiết bị ở trạng thái mở khoá trong thời gian dài hơn so với bình thường.

Nếu ứng dụng của bạn yêu cầu mức độ bảo mật cao hơn (chẳng hạn như khi hiển thị dữ liệu có khả năng nhạy cảm hoặc riêng tư), trước tiên, hãy kiểm tra xem tính năng phát hiện cổ tay có được bật hay không:

val wristDetectionEnabled =
        isWristDetectionAutoLockingEnabled(applicationContext)

Nếu giá trị trả về của phương thức này là false, hãy nhắc người dùng đăng nhập vào một tài khoản trong ứng dụng của bạn trước khi hiển thị nội dung dành riêng cho người dùng.

Trình quản lý thông tin xác thực

Trình quản lý thông tin xác thực là API được đề xuất để xác thực trên Wear OS. API này cung cấp một môi trường an toàn hơn để người dùng đăng nhập vào các ứng dụng Wear OS trong chế độ cài đặt độc lập, mà không cần điện thoại được ghép nối và không cần nhớ mật khẩu.

Tài liệu này trình bày thông tin mà nhà phát triển cần để triển khai giải pháp Trình quản lý thông tin đăng nhập bằng các cơ chế xác thực tiêu chuẩn mà giải pháp này lưu trữ, đó là:

  • Khoá truy cập
  • Mật khẩu
  • Danh tính liên kết (chẳng hạn như Đăng nhập bằng Google)

Hướng dẫn này cũng cung cấp chỉ dẫn về cách di chuyển các phương thức xác thực Wear OS được chấp nhận khác (Chia sẻ mã thông báo lớp dữ liệuOAuth) làm bản sao lưu cho Trình quản lý thông tin xác thực, cũng như chỉ dẫn đặc biệt để xử lý quá trình chuyển đổi từ Nút đăng nhập bằng Google độc lập (hiện không được dùng nữa) sang phiên bản Trình quản lý thông tin xác thực được nhúng.

Khoá truy cập trên Wear OS

Nhà phát triển nên triển khai khoá truy cập trong các hoạt động triển khai Credential Manager trên Wear OS. Khoá truy cập là tiêu chuẩn mới của ngành để xác thực người dùng cuối và mang lại một số lợi ích đáng kể cho người dùng.

Khoá truy cập dễ sử dụng hơn

  • Người dùng có thể chọn một tài khoản để đăng nhập. Họ không cần nhập tên người dùng.
  • Người dùng có thể xác thực bằng phương thức khoá màn hình của thiết bị.
  • Sau khi tạo và đăng ký khoá truy cập, người dùng có thể chuyển sang một thiết bị mới một cách liền mạch và sử dụng ngay mà không cần đăng ký lại.

Khoá truy cập an toàn hơn

  • Nhà phát triển chỉ lưu khoá công khai vào máy chủ thay vì lưu mật khẩu, tức là kẻ xấu sẽ ít có giá trị hơn khi xâm nhập vào máy chủ và ít phải dọn dẹp hơn trong trường hợp xảy ra vi phạm.
  • Khoá truy cập giúp bảo vệ bạn khỏi hành vi tấn công giả mạo. Khoá truy cập chỉ hoạt động trên những trang web và ứng dụng đã được đăng ký; người dùng không thể bị lừa xác thực trên một trang web lừa đảo vì trình duyệt hoặc hệ điều hành sẽ xử lý quy trình xác minh.
  • Khoá truy cập giúp giảm nhu cầu gửi tin nhắn SMS, nhờ đó giúp quá trình xác thực trở nên tiết kiệm chi phí hơn.

Triển khai khoá truy cập

Bao gồm chế độ thiết lập và hướng dẫn cho tất cả các loại triển khai.

Thiết lập

  1. Đặt cấp độ API mục tiêu thành 35 trong tệp build.gradle của mô-đun ứng dụng:

    android {
        defaultConfig {
            targetSdkVersion(35)
        }
    }
    
  2. Thêm các dòng sau vào tệp build.gradle cho ứng dụng hoặc mô-đun của bạn, bằng cách sử dụng phiên bản ổn định mới nhất trong tài liệu tham khảo các bản phát hành androidx.credentials.

    androidx.credentials:credentials:1.5.0
    androidx.credentials:credentials-play-services-auth:1.5.0
    

Phương thức xác thực tích hợp sẵn

Vì Trình quản lý thông tin xác thực là một API hợp nhất, nên các bước triển khai cho Wear OS cũng giống như đối với mọi loại thiết bị khác.

Sử dụng hướng dẫn dành cho thiết bị di động để bắt đầu và triển khai tính năng hỗ trợ khoá truy cập và mật khẩu.

Các bước để thêm tính năng hỗ trợ Đăng nhập bằng Google vào Trình quản lý thông tin xác thực hướng đến việc phát triển thiết bị di động, nhưng các bước này cũng tương tự trên Wear OS. Hãy xem phần Chuyển đổi từ tính năng Đăng nhập bằng Google cũ để biết những điểm cần lưu ý đặc biệt trong trường hợp này.

Xin lưu ý rằng bạn không thể tạo thông tin đăng nhập trên Wear OS, vì vậy, bạn không cần triển khai các phương thức tạo thông tin đăng nhập được đề cập trong hướng dẫn dành cho thiết bị di động.

Phương thức xác thực dự phòng

Có 2 phương thức xác thực khác được chấp nhận cho các ứng dụng Wear OS: OAuth 2.0 (một trong hai biến thể) và tính năng Chia sẻ lớp dữ liệu mã thông báo xác thực trên thiết bị di động. Mặc dù các phương thức này không có điểm tích hợp trong API Trình quản lý thông tin xác thực, nhưng bạn có thể đưa chúng vào quy trình trải nghiệm người dùng của Trình quản lý thông tin xác thực dưới dạng phương án dự phòng trong trường hợp người dùng đóng màn hình Trình quản lý thông tin xác thực.

Để xử lý hành động của người dùng khi đóng màn hình Trình quản lý thông tin xác thực, hãy nắm bắt NoCredentialException trong logic GetCredential và chuyển đến giao diện người dùng xác thực tuỳ chỉnh của riêng bạn.

yourCoroutineScope.launch {
    try {
      val response = credentialManager.getCredential(activity, request)
      signInWithCredential(response.credential)
    } catch (e: GetCredentialCancellationException) {
      navigateToFallbackAuthMethods()
    }
}

Sau đó, giao diện người dùng xác thực tuỳ chỉnh của bạn có thể cung cấp bất kỳ phương thức xác thực nào khác được chấp nhận như mô tả trong hướng dẫn về trải nghiệm người dùng đăng nhập.

Chia sẻ mã thông báo lớp dữ liệu

Ứng dụng đồng hành cho điện thoại có thể chuyển dữ liệu xác thực đến ứng dụng Wear OS một cách an toàn bằng cách sử dụng Wearable Data Layer API. Chuyển thông tin xác thực dưới dạng thông báo hoặc dưới dạng các mục dữ liệu.

Phương thức xác thực này thường không yêu cầu người dùng làm gì cả. Tuy nhiên, hãy tránh xác thực mà không thông báo cho người dùng về việc họ đang đăng nhập. Bạn có thể thông báo cho người dùng bằng một màn hình có thể đóng được, cho họ thấy tài khoản của họ đang được chuyển từ thiết bị di động sang.

Lưu ý quan trọng: Ứng dụng Wear OS của bạn phải cung cấp ít nhất một phương thức xác thực khác, vì lựa chọn này chỉ hoạt động trên các đồng hồ được ghép nối với Android khi ứng dụng di động tương ứng được cài đặt. Cung cấp một phương thức xác thực thay thế cho những người dùng không có ứng dụng di động tương ứng hoặc có thiết bị Wear OS được ghép nối với thiết bị iOS.

Truyền mã thông báo bằng lớp dữ liệu trong ứng dụng di động như minh hoạ trong ví dụ sau:

val token = "..." // Auth token to transmit to the Wear OS 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)

Theo dõi các sự kiện thay đổi dữ liệu trên ứng dụng Wear OS, như minh hoạ trong ví dụ sau:

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 an interstitial screen to notify the user that
                // they're being signed in.
                // Then, store the token and use it in network requests.
            }
        }
    }
}

Để biết thêm thông tin về cách sử dụng Lớp dữ liệu trên thiết bị đeo, hãy xem bài viết Gửi và đồng bộ hoá dữ liệu trên Wear OS.

Sử dụng OAuth 2.0

Wear OS hỗ trợ 2 luồng dựa trên OAuth 2.0 như được mô tả trong các phần sau:

  • Cấp mã uỷ quyền bằng Khoá bằng chứng để trao đổi mã (PKCE) theo mô tả trong RFC 7636
  • Cấp quyền cho thiết bị (DAG) theo mô tả trong RFC 8628
Khoá bằng chứng để trao đổi mã (PKCE)

Để sử dụng PKCE hiệu quả, hãy dùng RemoteAuthClient. Sau đó, để thực hiện yêu cầu xác thực từ ứng dụng Wear OS tới một trình cung cấp OAuth, hãy tạo một đối tượng OAuthRequest. Đối tượng này bao gồm một URL đến điểm cuối của OAuth để lấy mã thông báo và đối tượng CodeChallenge.

Mã sau đây là ví dụ về cách tạo một yêu cầu xác thực:

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

Sau khi tạo yêu cầu xác thực, hãy gửi yêu cầu đó đến ứng dụng đồng hành bằng cách sử dụng phương thức 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 any errors.
        }
    }
)

Yêu cầu này kích hoạt một lệnh gọi đến ứng dụng đồng hành, sau đó sẽ hiển thị giao diện người dùng uỷ quyền trong một trình duyệt web trên điện thoại di động của người dùng. Trình cung cấp OAuth 2.0 sẽ xác thực người dùng và xin sự đồng ý của người dùng đối với các quyền được yêu cầu. Phản hồi được gửi đến URL chuyển hướng được tạo tự động.

Sau khi uỷ quyền thành công hoặc không thành công, máy chủ OAuth 2.0 sẽ chuyển hướng đến URL được chỉ định trong yêu cầu. Nếu người dùng phê duyệt yêu cầu truy cập, thì phản hồi sẽ chứa mã uỷ quyền. Nếu người dùng không phê duyệt yêu cầu, thì phản hồi sẽ chứa thông báo lỗi.

Phản hồi có dạng chuỗi truy vấn và giống như một trong các ví dụ sau:

  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

Thao tác này sẽ tải một trang để hướng người dùng đến ứng dụng đồng hành. Ứng dụng đồng hành xác minh URL phản hồi và chuyển tiếp phản hồi đến ứng dụng Wear OS của bạn bằng API onAuthorizationResponse.

Sau đó, ứng dụng đồng hồ có thể trao đổi mã uỷ quyền để lấy mã truy cập.

Cấp quyền cho thiết bị

Khi sử dụng tính năng Cấp quyền (uỷ quyền) cho thiết bị, người dùng sẽ mở URI xác minh trên một thiết bị khác. Sau đó, máy chủ uỷ quyền sẽ yêu cầu người dùng phê duyệt hoặc từ chối yêu cầu.

Để giúp quá trình này dễ dàng hơn, hãy sử dụng RemoteActivityHelper để mở một trang web trên thiết bị di động đã ghép nối của người dùng như minh hoạ trong ví dụ sau:

// 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.

Nếu bạn có ứng dụng dành cho iOS, hãy sử dụng đường liên kết phổ quát để chặn ý định này trong ứng dụng của bạn thay vì dựa vào trình duyệt để cấp mã thông báo.

Chuyển đổi từ tính năng Đăng nhập bằng Google phiên bản cũ

Trình quản lý thông tin xác thực có một điểm tích hợp chuyên dụng cho nút Đăng nhập bằng Google. Trước đây, bạn có thể thêm nút này ở bất kỳ vị trí nào trong UX xác thực của ứng dụng, nhưng khi nút này được đưa vào Trình quản lý thông tin đăng nhập, lựa chọn cũ hiện không được dùng nữa.

// Define a basic SDK check.
fun isCredentialManagerAvailable(): Boolean {
 return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM
}

// Elsewhere in the code, use it to selectively disable the legacy option.
Button(
  onClick = {
    if (isCredentialManagerAvailable()) {
      Log.w(TAG, "Devices on API level 35 or higher should use
                  Credential Manager for Sign in with Google")
    } else {
      navigateToSignInWithGoogle()
    }},
  enabled = !isCredentialManagerAvailable(),
  label = { Text(text = stringResource(R.string.sign_in_with_google)) },
  secondaryLabel = { Text(text = "Disabled on API level 35+")
  }
)