پیاده‌سازی «ورود به سیستم با Google»

این راهنما نحوه پیاده‌سازی «ورود به سیستم با Google» را شرح می‌دهد و مراحل زیر را پوشش می‌دهد:

  • وابستگی‌ها را به برنامه‌تان اضافه کنید.
  • نمونه‌سازی CredentialManager.
  • جریان برگ زیرین را ایجاد کنید.
  • جریان دکمه را ایجاد کنید.
  • پاسخ ورود به سیستم را مدیریت کنید.
  • خطاها را مدیریت کنید.
  • خروج از سیستم را مدیریت کنید.

افزودن وابستگی‌ها به برنامه

در فایل build.gradle واحدتان، وابستگی‌ها را بااستفاده از جدیدترین نسخه Credential Manager،‏ Play Services Auth، و googleid اعلام کنید:

کاتلین

dependencies {
    implementation("androidx.credentials:credentials:1.7.0-alpha03")
    implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
    implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>")
}

شیار

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha03"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03"
    implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

نمونه‌سازی Credential Manager

از بافت برنامه یا فعالیتتان برای ایجاد شیء CredentialManager استفاده کنید.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

ایجاد کردن جریان برگ زیرین

برگ زیرین واسط کاربر داخلی «مدیر اعتبارنامه‌ها» است. استفاده از این میانای کاربر تجربه ثابتی را در همه روش‌های اصالت‌سنجی، مانند گذرواژه‌ها، گذرکلیدها، و «ورود به سیستم با Google» ایجاد می‌کند.

پیکربندی درخواست ورود به سیستم برای حساب‌های قبلاً مجازشده

با GetGoogleIdOption درخواست ورود به سیستم Google را امتحان کنید تا «شناسه Google» کاربر را بازیابی کنید.

قطعه‌های زیر بررسی می‌کنند که آیا حساب مجاز است یا نه.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    .setNonce(generateSecureRandomNonce())
    .build()

شیء googleIdOption درخواست به‌صورت زیر پیکربندی شده است:

  • فیلتر کردن حساب‌های قبلاً مجازشده: برای بازیابی حساب‌های مجازشده‌ای که قبلاً برای ورود به سیستم برنامه‌تان استفاده شده‌اند، setFilterByAuthorizedAccounts را روی true تنظیم کنید.

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

  • تنظیم شناسه کارخواه سرور: پارامتر setServerClientId را تنظیم کنید. webClientId «شناسه کارخواه وب» است که برای OAuth در «پروژه» Google Cloud خودتان هنگام تکمیل پیش‌نیازها راه‌اندازی کرده‌اید.

  • فعال کردن ورود خودکار به سیستم (اختیاری): برای فعال کردن ورود خودکار به سیستم برای کاربرانی که برمی‌گردند، از setAutoSelectEnabled(true) و setFilterByAuthorizedAccounts(true) استفاده کنید. برای کاربران برنامه‌تان، این کار اصطکاک غیرضروری را درصورتی‌که قبلاً به سیستم وارد شده باشند برطرف می‌کند.

    «ورود خودکار به سیستم» فقط زمانی امکان‌پذیر است که معیارهای زیر برآورده شود:

    • فقط یک حساب مجاز در دستگاه وجود دارد و آن حساب مجاز قبلاً برای ورود به سیستم برنامه در دستگاه استفاده شده است. وجود چند حساب مجاز در دستگاه، ورود خودکار به سیستم را غیرفعال می‌کند.
    • کاربر درطول جلسه قبلی خود به‌طور صریح از برنامه خارج نشده است.
    • کاربر «ورود خودکار به سیستم» را در تنظیمات «حساب Google» خود غیرفعال نکرده باشد.
  • تنظیم یک عدد یک‌بارمصرف (اختیاری): برای فعال کردن امنیت بهبودیافته، یک عدد یک‌بارمصرف برای درستی‌سنجی سمت سرور تنظیم کنید. برای جلوگیری از حملات بازپخش، می‌توانید یک عدد یک‌بارمصرف برای درستی‌سنجی سمت سرور با setNonce() اضافه کنید. مطمئن شوید که کد سمت سرور شما تأیید می‌کند که نانس‌های درخواست و پاسخ یکسان هستند.

    برای تولید کردن nonce، از تابعی مشابه تابع زیر استفاده کنید که یک nonce تصادفی قوی ازنظر رمزنگاری با طول مشخص تولید می‌کند و آن را بااستفاده از Base64 کدگذاری می‌کند:

fun generateSecureRandomNonce(byteLength: Int = 32): String {
    val randomBytes = ByteArray(byteLength)
    SecureRandom().nextBytes(randomBytes)
    return Base64.encodeToString(randomBytes, Base64.NO_WRAP or Base64.URL_SAFE or Base64.NO_PADDING)
}

درخواست ورود به سیستم

با فراخوانی روش getCredential، بررسی کنید که آیا کاربر حساب مجاز در دستگاه دارد یا نه:

val request: GetCredentialRequest = GetCredentialRequest.Builder()
    .addCredentialOption(googleIdOption)
    .build()

// Use an activity-based context to avoid undefined system UI
// launching behavior.
val mutableContext = MutableContextWrapper(activityContext)
coroutineScope {
    try {
        val result = credentialManager.getCredential(
            request = request,            
            context = mutableContext // Use MutableContextWrapper to avoid memory leak during configuration changes
        )
        handleSignIn(result)
    } catch (e: GetCredentialException) {
        // Handle failures
    }
}

اگر حساب مجاز دردسترس نیست، درخواست ورود به سیستم را پیکربندی کنید

اگر کاربر مجاز برای برنامه‌تان در دستگاه وجود نداشته باشد، CredentialManager NoCredentialException را برمی‌گرداند. در این سناریو، فیلتر حساب‌های مجاز را غیرفعال کنید تا کاربر بتواند با حساب دیگری ثبت‌نام کند.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId(WEB_CLIENT_ID)
    .setNonce(generateSecureRandomNonce())
    .build()

سپس، مشابه کاری که برای حساب‌های مجاز انجام دادید، درخواست ورود به سیستم کنید.

ایجاد کردن جریان دکمه

اگر می‌خواهید کاربران بتوانند در شرایط زیر از «ورود به سیستم با Google» استفاده کنند، از دکمه استفاده کنید:

  • کاربر واسط کاربر برگ زیرین «مدیر اطلاعات کاربری» را بست.
  • هیچ «حساب Google» در دستگاه وجود ندارد.
  • حساب‌های موجود در دستگاه به اصالت‌سنجی مجدد نیاز دارند.

ایجاد واسط کاربر دکمه

درحالی‌که این کار را می‌توان با دکمه Jetpack Compose انجام داد، می‌توانید از نماد نمانام ازپیش تأییدشده از صفحه رهنمودهای نمانام‌سازی «ورود به سیستم با Google» استفاده کنید.

ایجاد جریان ورود به سیستم

درخواست ورود به سیستم Google را با GetSignInWithGoogleOption ایجاد کنید تا «جتون شناسه Google» را بازیابی کنید.

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
    serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
    .build()

سپس، درخواست ورود به سیستم را مشابه آنچه برای واسط کاربر برگ زیرین انجام دادید ارسال کنید.

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

برای مدیریت ورود به سیستم، مراحل زیر را تکمیل کنید:

  1. از تابع getCredential() CredentialManager استفاده کنید. اگر پاسخ موفقیت‌آمیز بود، CustomCredential را استخراج کنید که باید از نوع GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL باشد.
  2. بااستفاده از روش GoogleIdTokenCredential.createFrom()، شیء را به GoogleIdTokenCredential تبدیل کنید.

  3. اعتبارنامه را در سرور طرف متکی خود اعتبارسنجی کنید.

  4. مطمئن شوید که خطاها را به‌درستی مدیریت می‌کنید.

fun handleSign(result: GetCredentialResponse) {
    // Handle the successfully returned credential.
    val credential = result.credential

    when (credential) {
        is CustomCredential -> {
            if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
                try {
                    // Use googleIdTokenCredential and extract the ID for server-side validation.
                    val googleIdTokenCredential = GoogleIdTokenCredential
                        .createFrom(credential.data)
                } catch (e: GoogleIdTokenParsingException) {
                    Log.e(TAG, "Received an invalid google id token response", e)
                }
            } else {
                // Catch any unrecognized credential type here.
                Log.e(TAG, "Unexpected type of credential")
            }
        }

        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential")
        }
    }
}

مدیریت کردن خطاها

خطاهای فهرست‌شده در عیب‌یابی را بررسی کنید تا مطمئن شوید کد شما همه سناریوهای خطای احتمالی را مدیریت می‌کند.

رسیدگی به خروج از سیستم

مهم است که سازوکاری برای کاربران فراهم کنید تا بتوانند از سیستم برنامه شما خارج شوند. برای مثال، ممکن است کاربر چند «حساب Google» در دستگاه داشته باشد و تصمیم بگیرد با حساب دیگری به سیستم وارد شود. می‌توانید این مورد را مثلاً در صفحه تنظیماتتان ارائه دهید.

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

وقتی کاربری از سیستم برنامه‌تان خارج می‌شود، روش API clearCredentialState() را فراخوانی کنید تا وضعیت اطلاعات کاربری کاربر فعلی از همه ارائه‌دهندگان اطلاعات کاربری پاک شود. این کار به همه ارائه‌دهندگان اطلاعات کاربری اطلاع می‌دهد که هرگونه جلسه اطلاعات کاربری ذخیره‌شده برای برنامه موردنظر باید پاک شود، تا دفعه بعد گزینه‌های کامل ورود به سیستم به کاربران ارائه شود.