اصالت‌سنجی در پوشیدنی‌ها: مدیر اعتبارنامه‌ها

برنامه‌های Wear OS می‌توانند بدون برنامه همراه و به‌صورت مستقل اجرا شوند. این یعنی برنامه Wear OS هنگام دسترسی به داده‌های اینترنت باید اصالت‌سنجی را به‌تنهایی مدیریت کند. اما اندازه کوچک صفحه ساعت و کاهش قابلیت‌های ورودی، گزینه‌های اصالت‌سنجی را که برنامه Wear OS می‌تواند استفاده کند محدود می‌کند.

این راهنما دستورالعمل‌هایی برای روش اصالت‌سنجی توصیه‌شده برای برنامه‌های Wear OS، یعنی «مدیر اطلاعات اعتباری»، ارائه می‌دهد.

برای کسب اطلاعات بیشتر درباره نحوه طراحی تجربه ورود به سیستم خوب، راهنمای تجربه کاربری ورود به سیستم را مشاهده کنید.

ملاحظات اولیه

قبل‌از شروع پیاده‌سازی، نکات زیر را درنظر بگیرید.

حالت مهمان

برای همه عملکردها اصالت‌سنجی الزامی نکنید. به‌جای آن، تا حد امکان ویژگی‌های زیادی را بدون نیاز به ورود به سیستم در اختیار کاربر قرار دهید.

کاربران ممکن است برنامه Wear شما را بدون استفاده از برنامه تلفن همراه پیدا و نصب کنند، بنابراین ممکن است حساب نداشته باشند و ندانند چه ویژگی‌هایی ارائه می‌دهد. مطمئن شوید کارکرد حالت مهمان ویژگی‌های برنامه‌تان را به‌درستی نمایش دهد.

قفل برخی‌از دستگاه‌ها ممکن است برای مدت طولانی‌تری باز بماند

در دستگاه‌های پشتیبانی‌شده که Wear OS 5 یا بالاتر را اجرا می‌کنند، سیستم تشخیص می‌دهد که آیا کاربر دستگاه را روی مچ دستش بسته است یا نه. اگر کاربر تشخیص مچ را خاموش کند و سپس دستگاه را از مچ خود بردارد، سیستم دستگاه را برای مدت طولانی‌تری نسبت‌به حالت عادی باز نگه می‌دارد.

اگر برنامه شما به سطح بالاتری از امنیت نیاز دارد—مثلاً هنگام نمایش داده‌های بالقوه حساس یا خصوصی—ابتدا بررسی کنید که آیا تشخیص مچ دست فعال است یا نه:

fun isWristDetectionAutoLockingEnabled(context: Context): Boolean {
    // Use the keyguard manager to check for the presence of a lock mechanism
    val keyguardManager = context.getSystemService<KeyguardManager>()
    val isSecured = keyguardManager?.isDeviceSecure == true

    // Use OEM-specific system settings to verify that on-body autolock is enabled.
    val isWristDetectionOn = android.provider.Settings.Global.getInt(
        context.contentResolver, PIXEL_WRIST_AUTOLOCK_SETTING_STATE,
        0
    ) == 1

    return isSecured && isWristDetectionOn
}

اگر مقدار برگشتی این روش false است، از کاربر بخواهید قبل‌از نمایش محتوای مختص کاربر، با حسابش در برنامه شما به سیستم وارد شود.

مدیر اطلاعات اعتباری

Credential Manager میانای برنامه‌سازی کاربردی توصیه‌شده برای اصالت‌سنجی در Wear OS است. این ویژگی محیطی امن‌تر برای کاربران فراهم می‌کند تا بدون نیاز به تلفن جفت‌شده متصل و بدون نیاز به به‌خاطر سپردن گذرواژه، در تنظیمات مستقل به سیستم برنامه‌های Wear OS وارد شوند.

این سند اطلاعاتی را که توسعه‌دهندگان برای پیاده‌سازی راه‌حل مدیر اطلاعات اعتباری با سازوکارهای اصالت‌سنجی استاندارد میزبانی‌شده در آن نیاز دارند، شرح می‌دهد. این سازوکارها عبارت‌اند از:

  • گذرکلیدها
  • گذرواژه‌ها
  • هویت‌های مشارکتی (مثل «ورود به سیستم با Google»)

این راهنما همچنین دستورالعمل‌هایی برای نحوه انتقال سایر روش‌های اصالت‌سنجی قابل‌قبول Wear OS (هم‌رسانی رمز لایه داده و OAuth) به‌عنوان پشتیبان برای Credential Manager ارائه می‌دهد و دستورالعمل‌های ویژه‌ای برای انتقال از دکمه مستقل «ورود به سیستم با Google» که اکنون منسوخ شده است به نسخه جاسازی‌شده Credential Manager ارائه می‌دهد.

محدودیت‌ها و تفاوت‌های Wear OS

توسعه‌دهندگان باید محدودیت‌ها و تفاوت‌های زیر را در Wear OS درنظر داشته باشند:

  • ‫Credential Manager در Wear OS 3 و نسخه‌های بالاتر دردسترس است.
  • اطلاعات اعتباری را نمی‌توان در Wear OS ایجاد کرد
  • نه بازگرداندن اعتبارنامه‌ها و نه جریان‌های ورود به سیستم ترکیبی پشتیبانی نمی‌شوند.
  • فقط «ارائه‌دهندگان اطلاعات اعتباری» با یکپارچه‌سازی‌های Wear OS می‌توانند از تلفن همراه مجدداً استفاده شوند.

گذرکلیدها در Wear OS

به توسعه‌دهندگان قویاً توصیه می‌شود که گذرکلیدها را در پیاده‌سازی‌های Wear OS Credential Manager پیاده‌سازی کنند. گذرکلیدها استاندارد صنعتی جدیدی برای اصالت‌سنجی کاربر نهایی هستند و مزایای قابل‌توجهی برای کاربران دارند.

گذرکلیدها آسان‌تر هستند

  • کاربران می‌توانند حسابی را برای ورود به سیستم انتخاب کنند. آن‌ها نیازی به تایپ کردن نام کاربری ندارند.
  • کاربران می‌توانند بااستفاده از قفل صفحه دستگاه اصالت‌سنجی کنند.
  • پس‌از ایجاد و ثبت گذرکلید، کاربر می‌تواند به‌راحتی به دستگاه جدیدی برود و بلافاصله بدون نیاز به ثبت‌نام مجدد از آن استفاده کند.

گذرکلیدها ایمن‌تر هستند

  • توسعه‌دهندگان به‌جای ذخیره کردن گذرواژه، فقط کلید عمومی را در سرور ذخیره می‌کنند، یعنی برای عامل مخرب ارزش بسیار کمتری دارد که به سرورها نفوذ کند، و درصورت نقض، پاک‌سازی بسیار کمتری لازم است.
  • گذرکلیدها محافظت دربرابر رمزگیری ارائه می‌دهند. گذرکلیدها فقط در وب‌سایت‌ها و برنامه‌های ثبت‌شده خودشان کار می‌کنند؛ کاربر نمی‌تواند فریب بخورد و در سایت فریبکارانه درستی‌سنجی کند زیرا مرورگر یا سیستم‌عامل درستی‌سنجی را انجام می‌دهد.
  • گذرکلیدها نیاز به ارسال پیامک را کاهش می‌دهند و اصالت‌سنجی را مقرون‌به‌صرفه‌تر می‌کنند.

پیاده‌سازی گذرکلیدها

شامل راه‌اندازی و راهنمایی برای همه انواع پیاده‌سازی می‌شود.

راه‌اندازی

  1. سطح میانای برنامه‌سازی کاربردی هدف را در فایل build.gradle واحد برنامه روی ۳۵ تنظیم کنید:

    android {
        defaultConfig {
            targetSdk(35)
        }
    }
    
  2. خطوط زیر را بااستفاده از جدیدترین نسخه پایدار از مرجع androidx.credentials نسخه‌های پخش به فایل build.gradle برای برنامه یا واحدتان اضافه کنید.

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

روش‌های اصالت‌سنجی داخلی

ازآنجایی‌که Credential Manager یک API یکپارچه است، مراحل پیاده‌سازی برای Wear OS با مراحل پیاده‌سازی برای هر نوع دستگاه دیگری یکسان است.

برای شروع و پیاده‌سازی پشتیبانی از گذرکلیدها و گذرواژه‌ها، از دستورالعمل‌های تلفن همراه استفاده کنید.

مراحل افزودن پشتیبانی «ورود به سیستم با Google» به Credential Manager برای توسعه تلفن همراه طراحی شده است، اما مراحل در Wear OS یکسان است.

توجه داشته باشید که ازآنجایی‌که نمی‌توانید در Wear OS اطلاعات اعتباری ایجاد کنید، لازم نیست روش‌های ایجاد اطلاعات اعتباری ذکرشده در دستورالعمل‌های تلفن همراه را پیاده‌سازی کنید.

روش‌های اصالت‌سنجی احتیاطی

دو روش اصالت‌سنجی قابل‌قبول دیگر برای برنامه‌های Wear OS وجود دارد: OAuth 2.0 (هر دو نوع) و «هم‌رسانی لایه داده رمز اصالت‌سنجی تلفن همراه». اگرچه این روش‌ها در Credential Manager API نقطه ادغام ندارند، اما می‌توانند در جریان UX مربوط به Credential Manager به‌عنوان روش‌های جایگزین درنظر گرفته شوند تا درصورتی‌که کاربران صفحه Credential Manager را ببندند، از آن‌ها استفاده شود.

برای مدیریت کنش کاربر در بستن صفحه «مدیر اطلاعات اعتباری»، NoCredentialException را به‌عنوان بخشی از GetCredential منطق خود دریافت کنید و به میانای کاربر سفارشی اصالت‌سنجی خودتان پیمایش کنید.

try {
    val getCredentialResponse: GetCredentialResponse =
        credentialManager.getCredential(activity, createGetCredentialRequest())
    return authenticate(getCredentialResponse.credential)
} catch (_: GetCredentialCancellationException) {
    navigateToSecondaryAuthentication()
}

سپس واسط کاربر احراز هویت سفارشی شما می‌تواند هریک از روش‌های احراز هویت قابل‌قبول دیگری را که در راهنمای تجربه کاربری ورود به سیستم توضیح داده شده است ارائه دهد.

هم‌رسانی کردن نشان لایه داده

برنامه همراه تلفن می‌تواند بااستفاده از Wearable Data Layer API داده‌های اصالت‌سنجی را به‌طور ایمن به برنامه Wear OS منتقل کند. انتقال اعتبارنامه‌ها به‌عنوان پیام یا به‌عنوان عناصر داده.

این نوع اصالت‌سنجی معمولاً نیازی به اقدام ازسوی کاربر ندارد. بااین‌حال، از اصالت‌سنجی بدون اطلاع کاربر از اینکه به سیستم وارد می‌شود خودداری کنید. می‌توانید بااستفاده از صفحه بستنی به کاربر اطلاع دهید که حسابش از تلفن همراه درحال انتقال است.

مهم: برنامه Wear OS شما باید حداقل یک روش اصالت‌سنجی دیگر ارائه دهد، زیرا این گزینه فقط در ساعت‌های جفت‌شده با Android که برنامه تلفن همراه مربوطه در آن‌ها نصب شده است کار می‌کند. روش اصالت‌سنجی جایگزینی برای کاربرانی که برنامه تلفن همراه مربوطه را ندارند یا دستگاه Wear OS آن‌ها با دستگاه iOS جفت شده است ارائه دهید.

گذرواژه‌های عبور را بااستفاده از لایه داده از برنامه تلفن همراه، همان‌طور که در مثال زیر نشان داده شده است، منتقل کنید:

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

همان‌طور که در مثال زیر نشان داده شده است، به رویدادهای تغییر داده در برنامه Wear OS گوش دهید:

class AuthDataListenerService : WearableListenerService() {
    override fun onDataChanged(dataEvents: DataEventBuffer) {
        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.
                    handleSignInSequence(token)
                }
            }
        }
    }

    /** placeholder sign in handler. */
    fun handleSignInSequence(token: String?) {}
}

برای کسب اطلاعات بیشتر درباره استفاده از «لایه داده‌های پوشیدنی»، به ارسال و همگام‌سازی داده‌ها در Wear OS مراجعه کنید.

استفاده از OAuth 2.0

‫Wear OS از دو جریان مبتنی بر OAuth 2.0 پشتیبانی می‌کند که در بخش‌های زیر توضیح داده شده‌اند:

  • اعطای کد مجوز با کلید اثبات برای تبادل کد (PKCE)، همان‌گونه که در RFC 7636 تعریف شده است
  • «اعطای مجوز دستگاه» (DAG)، همان‌گونه که در RFC 8628 تعریف شده است
کلید اثبات برای تبادل کد (PKCE)

برای استفاده مؤثر از PKCE، از RemoteAuthClient استفاده کنید. سپس، برای انجام درخواست اصالت‌سنجی از برنامه Wear OS به ارائه‌دهنده OAuth، شیء OAuthRequest ایجاد کنید. این شیء شامل نشانی وب نقطه پایان OAuth شما برای دریافت کد و یک شیء CodeChallenge است.

کد زیر نمونه‌ای از ایجاد درخواست اصالت‌سنجی را نشان می‌دهد:

val oauthRequest = OAuthRequest.Builder(context)
    .setAuthProviderUrl(uri)
    .setCodeChallenge(codeChallenge)
    .setClientId(CLIENT_ID)
    .build()

پس‌از ساختن درخواست اصالت‌سنجی، آن را بااستفاده از روش sendAuthorizationRequest() به برنامه همراه ارسال کنید:

RemoteAuthClient.create(context).sendAuthorizationRequest(
    request = oauthRequest,
    executor = { command -> command?.run() },
    clientCallback = object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it, and use it in requests.
            continuation.resume(parseCodeFromResponse(response))
        }
        override fun onAuthorizationError(request: OAuthRequest, errorCode: Int) {
            // Handle Errors
            continuation.resume(Result.failure(IOException("Authorization failed")))
        }
    }
)

این درخواست باعث می‌شود که تماسی با برنامه همراه برقرار شود، که سپس یک واسط کاربر مجوز در مرورگر وب در تلفن همراه کاربر ارائه می‌دهد. ارائه‌دهنده OAuth 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 به برنامه Wear OS شما منتقل می‌کند.

برنامه ساعت می‌تواند کد مجوز را با کد دسترسی مبادله کند.

اعطای مجوز دستگاه

هنگام استفاده از «اعطای مجوز دستگاه»، کاربر نشانی وب درستی‌سنجی را در دستگاه دیگری باز می‌کند. سپس سرور مجوز از او می‌خواهد درخواست را تأیید یا رد کند.

برای آسان‌تر کردن این فرایند، از RemoteActivityHelper برای باز کردن صفحه وب در دستگاه همراه جفت‌شده کاربر استفاده کنید، همان‌طور که در مثال زیر نشان داده شده است:

// Request access from the authorization server and receive Device Authorization Response.
private fun verifyDeviceAuthGrant(verificationUri: String) {
    RemoteActivityHelper(context).startRemoteActivity(
        Intent(Intent.ACTION_VIEW).apply {
            addCategory(Intent.CATEGORY_BROWSABLE)
            data = Uri.parse(verificationUri)
        },
        null
    )
}

اگر برنامه iOS دارید، از پیوندهای جهانی برای رهگیری این هدف در برنامه‌تان استفاده کنید و برای مجوز دادن به کد از مرورگر استفاده نکنید.