احراز هویت کاربران با ورود به سیستم با Google

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

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

برای تنظیم ورود با گوگل، این دو مرحله اصلی را دنبال کنید:

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

برگه پایین مدیریت اعتبارنامه
شکل ۱. رابط کاربری انتخاب اعتبارنامه در برگه پایینی Credential Manager

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

انیمیشنی که روند ورود با گوگل را نشان می‌دهد
شکل ۲. رابط کاربری دکمه ورود با گوگل در مدیریت اعتبارنامه

این سند نحوه ادغام دکمه ورود با گوگل و کادر محاوره‌ای برگه پایانی را با API مدیریت اعتبارنامه با استفاده از کتابخانه کمکی Google ID توضیح می‌دهد.

تنظیم کنید Google Cloud Console پروژه

  1. پروژه خود را درCloud Console یا اگر پروژه‌ای ندارید، آن را ایجاد کنید.
  2. رویBranding page ، مطمئن شوید که تمام اطلاعات کامل و دقیق است.
    1. مطمئن شوید که نام برنامه، لوگوی برنامه و صفحه اصلی برنامه به درستی به برنامه شما اختصاص داده شده است. این مقادیر در صفحه «ورود با رضایت گوگل» هنگام ثبت نام و صفحه «برنامه‌ها و خدمات شخص ثالث» به کاربران نمایش داده می‌شوند.
    2. مطمئن شوید که آدرس‌های اینترنتی (URL) مربوط به سیاست حفظ حریم خصوصی و شرایط خدمات برنامه خود را مشخص کرده‌اید.
  3. درClients page اگر از قبل یک شناسه کلاینت اندروید برای برنامه خود ندارید، آن را ایجاد کنید. باید نام بسته برنامه و امضای SHA-1 آن را مشخص کنید.
    1. برو بهClients page .
    2. روی ایجاد کلاینت کلیک کنید.
    3. نوع برنامه اندروید را انتخاب کنید.
    4. یک نام برای کلاینت OAuth وارد کنید. این نام در پوشه پروژه شما نمایش داده می‌شود.Clients page برای شناسایی مشتری.
    5. نام بسته‌ی برنامه‌ی اندروید خود را وارد کنید. این مقدار در ویژگی package عنصر <manifest> در فایل AndroidManifest.xml شما تعریف شده است.
    6. اثر انگشت گواهی امضای SHA-1 مربوط به توزیع برنامه را وارد کنید.
    7. اگر برنامه شما از امضای برنامه توسط Google Play استفاده می‌کند، اثر انگشت SHA-1 را از صفحه امضای برنامه در Play Console کپی کنید.
    8. اگر خودتان کلید اصلی و کلیدهای امضای خود را مدیریت می‌کنید، از ابزار keytool که در جاوا موجود است برای چاپ اطلاعات گواهی در قالبی قابل خواندن توسط انسان استفاده کنید. مقدار SHA-1 را در بخش Certificate fingerprints از خروجی keytool کپی کنید. برای اطلاعات بیشتر به بخش احراز هویت کلاینت خود در مستندات Google APIs for Android مراجعه کنید.
    9. (اختیاری) مالکیت برنامه اندروید خود را تأیید کنید .
  4. درClients page اگر قبلاً یک شناسه کلاینت «برنامه وب» جدید ایجاد نکرده‌اید، آن را ایجاد کنید. فعلاً می‌توانید فیلدهای «منشاهای جاوا اسکریپت مجاز» و «URIهای تغییر مسیر مجاز» را نادیده بگیرید. این شناسه کلاینت برای شناسایی سرور backend شما هنگام ارتباط با سرویس‌های احراز هویت گوگل استفاده خواهد شد.
    1. برو بهClients page .
    2. روی ایجاد کلاینت کلیک کنید.
    3. نوع برنامه وب را انتخاب کنید.

تأیید مالکیت برنامه

شما می‌توانید مالکیت برنامه خود را تأیید کنید تا خطر جعل هویت برنامه کاهش یابد.

برای تکمیل فرآیند تأیید، می‌توانید از حساب توسعه‌دهنده گوگل پلی خود استفاده کنید، البته اگر حساب دارید و برنامه شما در کنسول گوگل پلی ثبت شده است. برای تأیید موفقیت‌آمیز، شرایط زیر باید رعایت شود:

  • شما باید یک برنامه ثبت شده در کنسول گوگل پلی با نام بسته و اثر انگشت گواهی امضای SHA-1 مشابه با کلاینت OAuth اندروید که در حال تکمیل تأیید اعتبار برای آن هستید، داشته باشید.
  • شما باید در کنسول گوگل پلی، مجوز ادمین برای برنامه داشته باشید. درباره مدیریت دسترسی در کنسول گوگل پلی بیشتر بدانید .

در بخش «تأیید مالکیت برنامه» در کلاینت اندروید، روی دکمه «تأیید مالکیت» کلیک کنید تا فرآیند تأیید تکمیل شود.

اگر تأیید موفقیت‌آمیز باشد، اعلانی برای تأیید موفقیت‌آمیز بودن فرآیند تأیید نمایش داده می‌شود. در غیر این صورت، یک پیام خطا نمایش داده می‌شود.

برای رفع خطای تأیید ناموفق، موارد زیر را امتحان کنید:

  • مطمئن شوید برنامه‌ای که تأیید می‌کنید، یک برنامه ثبت‌شده در کنسول گوگل پلی است.
  • مطمئن شوید که در کنسول گوگل پلی، مجوز ادمین برای برنامه دارید.

اعلان وابستگی‌ها

وابستگی‌های زیر را به اسکریپت ساخت ماژول برنامه خود اضافه کنید - مطمئن شوید که <latest version> با آخرین نسخه کتابخانه googleid جایگزین می‌کنید:

کاتلین

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

شیار

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

درخواست ورود به سیستم گوگل را به صورت لحظه‌ای ایجاد کنید

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

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    // nonce string to use when generating a Google ID token
    .setNonce(nonce)
    .build()

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

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

فعال کردن ورود خودکار برای کاربران قدیمی (توصیه می‌شود)

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

برای فعال کردن ورود خودکار، از setAutoSelectEnabled(true) استفاده کنید. ورود خودکار فقط زمانی امکان‌پذیر است که معیارهای زیر رعایت شده باشد:

  • یک اعتبارنامه واحد با درخواست مطابقت دارد که می‌تواند یک حساب گوگل یا یک رمز عبور باشد و این اعتبارنامه با حساب پیش‌فرض در دستگاه اندروید مطابقت دارد.
  • کاربر صریحاً از سیستم خارج نشده است.
  • کاربر ورود خودکار را در تنظیمات حساب گوگل خود غیرفعال نکرده است.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    // nonce string to use when generating a Google ID token
    .setNonce(nonce)
    .build()

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

برای بهبود امنیت، یک nonce تنظیم کنید

برای بهبود امنیت ورود به سیستم و جلوگیری از حملات تکرار، setNonce اضافه کنید تا در هر درخواست، یک nonce لحاظ شود. درباره تولید nonce بیشتر بدانید .

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(true)
    // nonce string to use when generating a Google ID token
    .setNonce(nonce)
    .build()

ایجاد جریان ورود با گوگل

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

  1. یک GetCredentialRequest نمونه‌سازی کنید، سپس googleIdOption که قبلاً ایجاد شده را با استفاده از addCredentialOption() اضافه کنید تا اعتبارنامه‌ها را بازیابی کنید.
  2. این درخواست را به getCredential() (کوتلین) یا getCredentialAsync() (جاوا) ارسال کنید تا اعتبارنامه‌های موجود کاربر را بازیابی کنید.
  3. پس از موفقیت‌آمیز بودن API، CustomCredential که حاوی نتایج داده‌های GoogleIdTokenCredential است، استخراج کنید.
  4. نوع CustomCredential باید برابر با مقدار GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL باشد. شیء را با استفاده از متد GoogleIdTokenCredential.createFrom به یک GoogleIdTokenCredential تبدیل کنید.
  5. اگر تبدیل موفقیت‌آمیز بود، شناسه GoogleIdTokenCredential را استخراج کنید، آن را اعتبارسنجی کنید و اعتبارنامه را روی سرور خود تأیید کنید.

  6. اگر تبدیل با خطای GoogleIdTokenParsingException با شکست مواجه شد، ممکن است لازم باشد نسخه کتابخانه «ورود با گوگل» خود را به‌روزرسانی کنید.

  7. انواع اعتبارنامه‌های سفارشی ناشناخته را شناسایی کنید.

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

coroutineScope {
    try {
        val result = credentialManager.getCredential(
            request = request,
            context = activityContext,
        )
        handleSignIn(result)
    } catch (e: GetCredentialException) {
        // Handle failure
    }
}
fun handleSignIn(result: GetCredentialResponse) {
    // Handle the successfully returned credential.
    val credential = result.credential
    val responseJson: String

    when (credential) {

        // Passkey credential
        is PublicKeyCredential -> {
            // Share responseJson such as a GetCredentialResponse to your server to validate and
            // authenticate
            responseJson = credential.authenticationResponseJson
        }

        // Password credential
        is PasswordCredential -> {
            // Send ID and password to your server to validate and authenticate.
            val username = credential.id
            val password = credential.password
        }

        // GoogleIdToken credential
        is CustomCredential -> {
            if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
                try {
                    // Use googleIdTokenCredential and extract the ID to validate and
                    // authenticate on your server.
                    val googleIdTokenCredential = GoogleIdTokenCredential
                        .createFrom(credential.data)
                    // You can use the members of googleIdTokenCredential directly for UX
                    // purposes, but don't use them to store or control access to user
                    // data. For that you first need to validate the token:
                    // pass googleIdTokenCredential.getIdToken() to the backend server.
                    // see [validation instructions](https://developers.google.com/identity/gsi/web/guides/verify-google-id-token)
                } catch (e: GoogleIdTokenParsingException) {
                    Log.e(TAG, "Received an invalid google id token response", e)
                }
            } else {
                // Catch any unrecognized custom credential type here.
                Log.e(TAG, "Unexpected type of credential")
            }
        }

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

فعال کردن دکمه ورود با گوگل

برای فعال کردن دکمه‌ی ورود با گوگل، به جای GetGoogleIdOption از GetSignInWithGoogleOption استفاده کنید:

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

همانطور که در مثال کد زیر توضیح داده شده است GoogleIdTokenCredential برگشتی را مدیریت کنید.

fun handleSignInWithGoogleOption(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 id to validate and
                    // authenticate on your server.
                    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")
        }
    }
}

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

فعال کردن ثبت نام برای کاربران جدید (توصیه می‌شود)

ورود با گوگل ساده‌ترین راه برای کاربران است تا تنها با چند لمس، یک حساب کاربری جدید در برنامه یا سرویس شما ایجاد کنند.

اگر هیچ اعتبارنامه ذخیره‌شده‌ای یافت نشد (هیچ حساب گوگلی توسط getGoogleIdOption برگردانده نشد)، از کاربر بخواهید ثبت‌نام کند. ابتدا، بررسی کنید که آیا setFilterByAuthorizedAccounts(true) وجود دارد یا خیر تا ببینید آیا حساب‌های کاربری قبلاً استفاده‌شده‌ای وجود دارند یا خیر. اگر هیچ حسابی یافت نشد، با استفاده از setFilterByAuthorizedAccounts(false) از کاربر بخواهید با حساب گوگل خود ثبت‌نام کند.

مثال:

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

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

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

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

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