اصالت‌سنجی با Firebase بااستفاده از پیوند ایمیل در Android

می‌توانید از Firebase Authentication برای ورود کاربر به سیستم با ارسال ایمیلی حاوی پیوند استفاده کنید که کاربر می‌تواند روی آن کلیک کند تا وارد سیستم شود. در این فرایند، نشانی ایمیل کاربر نیز درستی‌سنجی می‌شود.

مزایای متعددی برای ورود به سیستم ازطریق ایمیل وجود دارد:

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

قبل از شروع

راه‌اندازی پروژه Android

  1. اگر قبلاً این کار را نکرده‌اید، ‫Firebase را به پروژه Android خود اضافه کنید.

  2. در فایل Gradle واحد (سطح برنامه) (معمولاً <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle)، وابستگی کتابخانه Firebase Authentication را برای Android اضافه کنید. توصیه می‌کنیم از Firebase Android BoM برای کنترل نسخه‌بندی کتابخانه استفاده کنید.

    همچنین، به‌عنوان بخشی از راه‌اندازی Firebase Authentication، باید کیت توسعه نرم‌افزار خدمات Google Play را به برنامه‌تان اضافه کنید.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:35.0.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:22.0.0")
    }

    بااستفاده از Firebase Android BoM، برنامه شما همیشه از نسخه‌های سازگار کتابخانه‌های Firebase Android استفاده خواهد کرد.

    (جایگزین)  افزودن وابستگی‌های کتابخانه Firebase بدون استفاده از BoM

    اگر انتخاب کنید که از Firebase BoM استفاده نکنید، باید نسخه هر کتابخانه Firebase را در خط وابستگی آن مشخص کنید.

    توجه داشته باشید که اگر از چند کتابخانه Firebase در برنامه‌تان استفاده می‌کنید، قویاً توصیه می‌کنیم از BoM برای مدیریت نسخه‌های کتابخانه استفاده کنید، که تضمین می‌کند همه نسخه‌ها سازگار باشند.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:25.0.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:22.0.0")
    }

فعال کردن ورود به سیستم با پیوند ایمیل برای پروژه Firebase

برای ورود به سیستم کاربران ازطریق پیوند ایمیل، ابتدا باید «ارائه‌دهنده ایمیل» و روش ورود به سیستم «پیوند ایمیل» را برای پروژه Firebase خود فعال کنید:

  1. در کنسول Firebase، به امنیت > اصالت‌سنجی بروید.

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

  3. در همان بخش، ارائه‌دهنده ورود به سیستم پیوند ایمیل (ورود به سیستم بدون گذرواژه) را فعال کنید.

  4. روی ذخیره کردن کلیک کنید.

برای شروع جریان اصالت‌سنجی، میانایی به کاربر ارائه دهید که از او بخواهد نشانی ایمیلش را ارائه دهد و سپس با sendSignInLinkToEmail تماس بگیرید و از Firebase بخواهید پیوند اصالت‌سنجی را به ایمیل کاربر ارسال کند.

  1. شیء ActionCodeSettings را بسازید که دستورالعمل‌هایی درباره نحوه ساختن پیوند ایمیل به Firebase ارائه می‌دهد. فیلدهای زیر را تنظیم کنید:

    • ‫url: پیوند عمیق برای جاسازی و هر وضعیت اضافی که باید منتقل شود. اگر قبلاً این کار را نکرده‌اید، دامنه پیوند را به فهرست دامنه‌های مجاز اضافه کنید:

      1. در کنسول Firebase، به امنیت > اصالت‌سنجی > زبانه تنظیمات بروید.

      2. در بخش دامنه‌های مجاز، روی افزودن دامنه کلیک کنید و دامنه پیوند را اضافه کنید.

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

    • ‫androidPackageName و iOSBundleId: به Firebase Authentication کمک می‌کند تعیین کند پیوند فقط وب یا پیوند تلفن همراه ایجاد کند که در دستگاه Android یا Apple باز می‌شود.
    • ‫handleCodeInApp: روی درست تنظیم کنید. برخلاف دیگر اقدامات ایمیلی خارج از باند (بازنشانی گذرواژه و درستی‌سنجی ایمیل)، عملیات ورود به سیستم همیشه باید در برنامه تکمیل شود. به‌دلیل اینکه در پایان جریان، کاربر باید به سیستم وارد شده باشد و وضعیت «احراز هویت» او در برنامه حفظ شده باشد.
    • linkDomain: وقتی دامنه‌های پیوند سفارشی Hosting برای پروژه‌ای تعریف می‌شود، مشخص کنید که وقتی پیوند باید با برنامه تلفن همراه مشخصی باز شود، از کدام دامنه استفاده شود. درغیراین‌صورت، دامنه پیش‌فرض به‌طور خودکار انتخاب می‌شود (برای مثال، PROJECT_ID.firebaseapp.com).
    • ‫dynamicLinkDomain: منسوخ. این پارامتر را مشخص نکنید.

    Kotlin

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
            "com.example.android",
            true, // installIfNotAvailable
            "12", // minimumVersion
        )
    }

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    برای کسب اطلاعات بیشتر درباره «تنظیمات کد کنش»، به بخش گذراندن وضعیت در کنش‌های ایمیل مراجعه کنید.

  2. نشانی ایمیل کاربر را بپرسید.

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

    Kotlin

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Email sent.")
            }
        }

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

نگرانی‌های امنیتی

برای جلوگیری از استفاده از پیوند ورود به سیستم برای ورود به سیستم به‌عنوان کاربر ناخواسته یا در دستگاه ناخواسته، Firebase Authentication نیاز دارد که نشانی ایمیل کاربر هنگام تکمیل جریان ورود به سیستم ارائه شود. برای اینکه ورود به سیستم موفقیت‌آمیز باشد، این نشانی ایمیل باید با نشانی‌ای که پیوند ورود به سیستم در ابتدا به آن ارسال شده است مطابقت داشته باشد.

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

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

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

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

‫Firebase Authentication از Firebase Hosting برای ارسال پیوند ایمیل به دستگاه همراه استفاده می‌کند. برای تکمیل ورود به سیستم ازطریق برنامه تلفن همراه، برنامه باید به‌گونه‌ای پیکربندی شود که پیوند برنامه ورودی را شناسایی کند، پیوند عمیق زیرین را تجزیه کند، و سپس ورود به سیستم را تکمیل کند. برای کسب اطلاعات بیشتر، مستندات پیوندهای برنامه Android را ببینید.

پیکربندی Firebase Hosting

‫Firebase Authentication هنگام ایجاد و ارسال پیوندی که قرار است در برنامه تلفن همراه باز شود از دامنه‌های Firebase Hosting استفاده می‌کند. دامنه Firebase Hosting پیش‌فرضی ازقبل برای شما پیکربندی شده است.

  1. پیکربندی Firebase Hosting دامنه:

    در کنسول Firebase، به میزبانی و بدون سرور > میزبانی بروید.

    • اگر می‌خواهید از دامنه پیش‌فرض برای پیوند ایمیلی که در برنامه‌های تلفن همراه باز می‌شود استفاده کنید، به سایت پیش‌فرضتان بروید و دامنه پیش‌فرض Hosting را یادداشت کنید. دامنه پیش‌فرض Hosting معمولاً به‌شکل زیر است: PROJECT_ID.firebaseapp.com.

      وقتی برنامه‌تان را برای رهگیری پیوند ورودی پیکربندی می‌کنید، به این مقدار نیاز خواهید داشت.

    • اگر می‌خواهید از دامنه سفارشی برای پیوند ایمیل استفاده کنید، می‌توانید دامنه سفارشی را در Firebase Hosting ثبت کنید و از آن برای دامنه پیوند استفاده کنید.

  2. پیکربندی برنامه‌های Android:

    برای مدیریت این پیوندها از برنامه Android خود، نام بسته برنامه شما باید در تنظیمات پروژه کنسول Firebase مشخص شود. علاوه‌براین، SHA-1 و SHA-256 گواهینامه برنامه باید ارائه شود.

    اگر می‌خواهید این پیوندها به فعالیت خاصی هدایت شوند، باید فیلتر هدفی را در فایل AndroidManifest.xml پیکربندی کنید. فیلتر هدف باید پیوندهای ایمیل دامنه شما را بگیرد. در AndroidManifest.xml:

    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data
        android:scheme="https"
        android:host="<PROJECT_ID>.firebaseapp.com or your custom domain"
        android:pathPrefix="/__/auth/links" />
    </intent-filter>
    

    وقتی کاربران پیوند میزبانی را با مسیر /__/auth/links و طرح و میزبان مشخص‌شده باز می‌کنند، برنامه شما فعالیت را با این فیلتر هدف شروع می‌کند تا پیوند را مدیریت کند.

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

Kotlin

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully signed in with email link!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error signing in with email link", task.exception)
            }
        }
}

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

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

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

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

تفاوت در نیمه دوم عملیات خواهد بود:

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d(TAG, "Successfully linked emailLink credential!")
            val result = task.result
            // You can access the new user via result.getUser()
            // Additional user info profile *not* available via:
            // result.getAdditionalUserInfo().getProfile() == null
            // You can check if the user is new or existing:
            // result.getAdditionalUserInfo().isNewUser()
        } else {
            Log.e(TAG, "Error linking emailLink credential", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

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

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is now successfully reauthenticated
        } else {
            Log.e(TAG, "Error reauthenticating", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

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

اصالت‌سنجی پیوند ایمیل قبلاً به Firebase Dynamic Links متکی بود که در ۲۵ اوت ۲۰۲۵ بسته خواهد شد.

راه‌حل جایگزینی در Firebase Authentication Android SDK v23.2.0+ و Firebase BoM v33.9.0+ منتشر کرده‌ایم.

اگر برنامه شما از پیوندهای سبک قدیمی استفاده می‌کند، باید برنامه‌تان را به سیستم جدید مبتنی بر Firebase Hosting انتقال دهید.

اگر پروژه خود را در تاریخ ۱۵ سپتامبر ۲۰۲۳ یا پس‌از آن ایجاد کرده‌اید، محافظت از شمارش ایمیل به‌طور پیش‌فرض فعال است. این ویژگی امنیت حساب‌های کاربری پروژه شما را بهبود می‌بخشد، اما روش fetchSignInMethodsForEmail() را که قبلاً برای پیاده‌سازی جریان‌های شناسه-اول توصیه می‌کردیم غیرفعال می‌کند.

اگرچه می‌توانید محافظت از شمارش ایمیل را برای پروژه‌تان غیرفعال کنید، اما توصیه می‌کنیم این کار را انجام ندهید.

برای جزئیات بیشتر، مستندات مربوط به محافظت از شمارش ایمیل را ببینید.

مراحل بعدی

پس‌از اینکه کاربر برای اولین‌بار به سیستم وارد شد، حساب کاربری جدیدی ایجاد می‌شود و به اطلاعات اعتباری—یعنی نام کاربری و گذرواژه، شماره تلفن، یا اطلاعات ارائه‌دهنده اصالت‌سنجی—که کاربر با آن به سیستم وارد شده است پیوند داده می‌شود. این حساب جدید به‌عنوان بخشی از پروژه Firebase شما ذخیره می‌شود و می‌توان از آن برای شناسایی کاربر در همه برنامه‌های پروژه شما، صرف‌نظر از نحوه ورود کاربر به سیستم، استفاده کرد.

  • در برنامه‌هایتان، می‌توانید اطلاعات نمایه پایه کاربر را از FirebaseUser شیء دریافت کنید. مدیریت کاربران را ببینید.

  • در Firebase Realtime Database و Cloud Storage قوانین امنیتی، می‌توانید شناسه کاربر یکتای کاربر واردشده به سیستم را از متغیر auth دریافت کنید و از آن برای کنترل داده‌هایی که کاربر می‌تواند به آن‌ها دسترسی داشته باشد استفاده کنید.

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

برای خروج از سیستم کاربر، signOut را فراخوانی کنید:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();