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

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

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

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

ملاحظات مقدماتی

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

حالت مهمان

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

کاربران ممکن است برنامه 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 وارد شوند.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

راه‌اندازی

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

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

    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 ندارند، می‌توان آن‌ها را در جریان تجربه کاربری Credential Manager به‌عنوان روش‌های جایگزین گنجاند تا درصورت رد کردن صفحه Credential Manager توسط کاربران، از آن‌ها استفاده شود.

برای رسیدگی به کنش کاربر در بستن صفحه «مدیر اطلاعات کاربری»، GetCredentialCancellationException را به‌عنوان بخشی از منطق 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 دارید، از پیوندهای جامع برای رهگیری این هدف در برنامه‌تان استفاده کنید، به‌جای اینکه برای صدور مجوز برای کد به مرورگر متکی باشید.