ورود با گوگل را پیاده‌سازی کنید

این راهنما نحوه پیاده‌سازی ورود با گوگل را شرح می‌دهد و مراحل زیر را پوشش می‌دهد:

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

وابستگی‌ها را به برنامه خود اضافه کنید

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

کاتلین

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

شیار

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

مدیر اعتبارنامه را به صورت نمونه معرفی کنید

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

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

جریان برگه پایینی را ایجاد کنید

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

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

با استفاده از GetGoogleIdOption درخواست ورود به سیستم گوگل را برای بازیابی توکن شناسه گوگل کاربر ارسال کنید.

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

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) استفاده کنید. برای کاربران برنامه شما، این کار در صورتی که قبلاً وارد سیستم شده باشند، اصطکاک غیرضروری را از بین می‌برد.

    ورود خودکار فقط در صورت رعایت معیارهای زیر امکان‌پذیر است:

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

    برای تولید 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()

coroutineScope {
    try {
        val result = credentialManager.getCredential(
            request = request,
            context = activityContext,
        )
        handleSignIn(result)
    } catch (e: GetCredentialException) {
        // Handle failures
    }
}

پیکربندی درخواست ورود به سیستم در صورت عدم وجود حساب‌های کاربری مجاز

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

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

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

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

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

  • کاربر رابط کاربری برگه پایانی Credential Manager را رد کرد.
  • هیچ حساب گوگلی روی دستگاه وجود ندارد.
  • حساب‌های کاربری موجود در دستگاه نیاز به احراز هویت مجدد دارند.

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

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

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

برای دریافت توکن شناسه گوگل، با استفاده از GetSignInWithGoogleOption یک درخواست ورود به سیستم گوگل ایجاد کنید.

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")
        }
    }
}

مدیریت خطاها

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

مدیریت خروج از سیستم

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

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

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