با استفاده از Apple در Android احراز هویت کنید

با استفاده از Firebase SDK می توانید به کاربران خود اجازه دهید با استفاده از Apple ID خود با Firebase احراز هویت کنند تا جریان ورود به سیستم OAuth 2.0 را به صورت کامل انجام دهند.

قبل از اینکه شروع کنی

برای ورود کاربران با استفاده از Apple ، ابتدا ورود به سیستم با Apple را در سایت توسعه دهندگان Apple پیکربندی کنید ، سپس Apple را به عنوان ارائه دهنده ورود به سیستم پروژه Firebase خود فعال کنید.

به برنامه توسعه دهندگان اپل بپیوندید

ورود به سیستم با اپل تنها می تواند توسط اعضای پیکربندی اپل توسعهدهنده برنامه .

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

در توسعه اپل سایت زیر را انجام دهید:

  1. مرتبط کردن وبسایت خود را به برنامه خود را به عنوان در بخش اول از توصیف پیکربندی ورود به سیستم با اپل برای وب . وقتی از شما خواسته شد ، URL زیر را به عنوان یک URL بازگشت ثبت کنید:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    شما می توانید فایربیس ID پروژه خود را در گرفتن صفحه فایربیس کنسول تنظیمات .

    پس از اتمام کار ، به شناسه سرویس جدید خود توجه کنید ، که در قسمت بعدی به آن نیاز خواهید داشت.

  2. درست ورود به سیستم با کلید خصوصی اپل . در قسمت بعدی به کلید خصوصی جدید و شناسه کلید خود نیاز دارید.
  3. اگر شما استفاده از هر یک از ویژگی فایربیس احراز هویت که ارسال ایمیل به کاربران، از جمله لینک ایمیل ورود به سیستم، تأیید آدرس ایمیل، تغییر حساب ابطال، و دیگران، پیکربندی سرویس رله ایمیل خصوصی اپل و ثبت نام noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (یا دامنه قالب ایمیل سفارشی شما) تا اپل بتواند ایمیل های ارسال شده توسط تأیید هویت Firebase را به آدرس های ایمیل ناشناس اپل منتقل کند.

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

  1. اضافه کردن فایربیس به پروژه آندروید خود را . هنگام تنظیم برنامه در کنسول Firebase ، حتماً امضای SHA-1 برنامه خود را ثبت کنید.
  2. در فایربیس کنسول ، باز کردن بخش تایید. بر روی ثبت نام در تب روش، فعال کردن ارائه دهنده اپل. شناسه خدماتی را که در قسمت قبل ایجاد کرده اید مشخص کنید. همچنین، در کد OAuth حفظ بخش پیکربندی جریان، مشخص خود را اپل کد تیم و کلید خصوصی و شناسایی کلید شما در بخش قبلی ایجاد شده است.

از الزامات داده ناشناس اپل پیروی کنید

ورود به سیستم با اپل به کاربران می دهد این گزینه از بی نام داده، از جمله آدرس ایمیل خود، هنگامی که ورود به سیستم. کاربرانی که این گزینه را انتخاب کنید آدرس ایمیل با دامنه privaterelay.appleid.com . هنگامی که از برنامه ورود به سیستم با Apple در برنامه خود استفاده می کنید ، باید از هرگونه خط مشی توسعه دهنده یا شرایط مربوط به Apple در مورد این شناسه های ناشناس Apple استفاده کنید.

این شامل اخذ رضایت کاربر مورد نیاز قبل از ارتباط مستقیم اطلاعات شخصی با یک Apple ID ناشناس است. هنگام استفاده از احراز هویت Firebase ، این ممکن است شامل اقدامات زیر باشد:

  • پیوند آدرس ایمیل به Apple ID ناشناس یا برعکس.
  • یک شماره تلفن را به Apple ID ناشناس یا بالعکس پیوند دهید
  • یک شناسنامه اجتماعی ناشناس (فیس بوک ، گوگل و غیره) را به Apple ID ناشناس پیوند دهید یا برعکس.

لیست بالا جامع نیست. در قسمت عضویت در حساب توسعه دهنده خود به موافقت نامه مجوز برنامه توسعه دهندگان Apple مراجعه کنید تا مطمئن شوید برنامه شما با الزامات Apple مطابقت دارد.

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

در Android ، ساده ترین راه برای احراز هویت کاربران با Firebase با استفاده از حساب های Apple آنها این است که تمام جریان ورود به سیستم را با Firebase Android SDK مدیریت کنیم.

برای مدیریت جریان ورود به سیستم با Firebase Android SDK ، این مراحل را دنبال کنید:

  1. ساخت یک نمونه از یک OAuthProvider با استفاده از سازنده آن با ID ارائه دهنده apple.com :

    جاوا

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    
  2. اختیاری: مشخص OAuth حفظ 2.0 حوزه فراتر از پیش فرض که شما به درخواست از ارائه دهنده احراز هویت می خواهید.

    جاوا

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("email");
            add("name");
          }
        };
    provider.setScopes(scopes);
    

    Kotlin+KTX

    provider.setScopes(arrayOf("email", "name"))
    

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

  3. اختیاری: اگر شما می خواهید برای نمایش اپل در صفحه ورود در یک زبان غیر از انگلیسی، مجموعه ای از locale پارامتر. مشاهده ورود به سیستم با اسناد اپل برای مناطق پشتیبانی شده است.

    جاوا

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    
  4. با استفاده از شیء ارائه دهنده OAuth با Firebase احراز هویت کنید. توجه داشته باشید که بر خلاف دیگر FirebaseAuth عملیات، این کنترل UI خود را با باز کردن یک برگه Chrome سفارشی. در نتیجه، انجام فعالیت های خود را در مرجع نه OnSuccessListener و OnFailureListener که شما ضمیمه به عنوان آنها بلافاصله جدا زمانی که عملیات شروع می شود از UI.

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

    برای بررسی اینکه آیا نتیجه انتظار وجود دارد، پاسخ getPendingAuthResult() :

    جاوا

    mAuth = FirebaseAuth.getInstance();
    Task<AuthResult> pending = mAuth.getPendingAuthResult();
    if (pending != null) {
        pending.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                Log.d(TAG, "checkPending:onSuccess:" + authResult);
                // Get the user profile with authResult.getUser() and
                // authResult.getAdditionalUserInfo(), and the ID
                // token from Apple with authResult.getCredential().
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "checkPending:onFailure", e);
            }
        });
    } else {
        Log.d(TAG, "pending: null");
    }
    

    Kotlin+KTX

    val pending = auth.pendingAuthResult
    if (pending != null) {
        pending.addOnSuccessListener { authResult ->
            Log.d(TAG, "checkPending:onSuccess:$authResult")
            // Get the user profile with authResult.getUser() and
            // authResult.getAdditionalUserInfo(), and the ID
            // token from Apple with authResult.getCredential().
        }.addOnFailureListener { e ->
            Log.w(TAG, "checkPending:onFailure", e)
        }
    } else {
        Log.d(TAG, "pending: null")
    }
    

    اگر هیچ نتیجه انتظار وجود دارد، شروع به ثبت نام در جریان، با تماس startActivityForSignInWithProvider() :

    جاوا

    mAuth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Sign-in successful!
                            Log.d(TAG, "activitySignIn:onSuccess:" + authResult.getUser());
                            FirebaseUser user = authResult.getUser();
                            // ...
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "activitySignIn:onFailure", e);
                        }
                    });
    

    Kotlin+KTX

    auth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener { authResult ->
                // Sign-in successful!
                Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                val user = authResult.user
                // ...
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "activitySignIn:onFailure", e)
            }
    

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

    همچنین، هنگامی که کاربر بخواهد به اشتراک گذاشتن ایمیل خود را با این برنامه، مفاد اپل یک آدرس ایمیل منحصر به فرد برای آن کاربر (از فرم نمی xyz@privaterelay.appleid.com )، آن سهام با برنامه شما. اگر سرویس رله ایمیل خصوصی را پیکربندی کرده اید ، اپل ایمیل های ارسال شده به آدرس ناشناس را به آدرس ایمیل واقعی کاربر ارسال می کند.

    اپل این اطلاعات را تنها سهام کاربر مانند نام نمایش با برنامه های اولین بار که کاربر در. معمولا، فروشگاه های فایربیس نام صفحه نمایش اولین بار که کاربر با شرکت اپل، که شما می توانید با گرفتن getCurrentUser().getDisplayName() . با این حال ، اگر قبلاً از Apple برای ورود کاربر به برنامه بدون استفاده از Firebase استفاده کرده اید ، اپل نام نمایشی کاربر را به Firebase ارائه نمی دهد.

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

همین الگو را می توان با استفاده startActivityForReauthenticateWithProvider() که شما می توانید برای بازیابی یک اعتبارنامه تازه برای عملیات حساس که نیاز به ورود به سیستم جدید استفاده کنید:

جاوا

// The user is already signed-in.
FirebaseUser firebaseUser = mAuth.getCurrentUser();

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener(
        new OnSuccessListener<AuthResult>() {
          @Override
          public void onSuccess(AuthResult authResult) {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
          }
        })
    .addOnFailureListener(
        new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Handle failure.
          }
        });

Kotlin+KTX

// The user is already signed-in.
val firebaseUser = auth.getCurrentUser()

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener( authResult -> {
        // User is re-authenticated with fresh tokens and
        // should be able to perform sensitive operations
        // like account deletion and email or password
        // update.
    })
    .addOnFailureListener( e -> {
        // Handle failure.
    })

و شما می توانید با استفاده از linkWithCredential() ، لینک ارائه دهندگان هویت های مختلف به حساب های موجود.

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

به عنوان مثال ، برای پیوند دادن حساب فیس بوک به حساب فعلی Firebase ، از رمز دسترسی که از ورود کاربر به فیس بوک دریافت کرده اید استفاده کنید:

جاوا

// Initialize a Facebook credential with a Facebook access token.
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      }
    });

Kotlin+KTX

// Initialize a Facebook credential with a Facebook access token.
val credential = FacebookAuthProvider.getCredential(token.getToken())

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, task -> {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      });

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

شما همچنین می توانید با Firebase با استفاده از یک حساب اپل توسط دست زدن به جریان ورود به سیستم یا با استفاده از اپل ثبت نام در JS SDK، دستی ساخت و ساز جریان OAuth تأیید یا با استفاده از کتابخانه OAuth مانند تصدیق AppAuth .

  1. برای هر درخواست ورود به سیستم ، یک رشته تصادفی ایجاد کنید-یک "nonce"-که از آن استفاده خواهید کرد تا مطمئن شوید که شناسه ای که دریافت می کنید به طور خاص در پاسخ به درخواست احراز هویت برنامه شما اعطا شده است. این مرحله برای جلوگیری از حملات تکراری مهم است.

    شما می توانید یک فعلی رمز نویسی امن در آندروید با تولید SecureRandom ، همانطور که در مثال زیر:

    جاوا

    private String generateNonce(int length) {
        SecureRandom generator = new SecureRandom();
    
        CharsetDecoder charsetDecoder = StandardCharsets.US_ASCII.newDecoder();
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE);
    
        byte[] bytes = new byte[length];
        ByteBuffer inBuffer = ByteBuffer.wrap(bytes);
        CharBuffer outBuffer = CharBuffer.allocate(length);
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes);
            inBuffer.rewind();
            charsetDecoder.reset();
            charsetDecoder.decode(inBuffer, outBuffer, false);
        }
        outBuffer.flip();
        return outBuffer.toString();
    }
    

    Kotlin+KTX

    private fun generateNonce(length: Int): String {
        val generator = SecureRandom()
    
        val charsetDecoder = StandardCharsets.US_ASCII.newDecoder()
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE)
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE)
    
        val bytes = ByteArray(length)
        val inBuffer = ByteBuffer.wrap(bytes)
        val outBuffer = CharBuffer.allocate(length)
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes)
            inBuffer.rewind()
            charsetDecoder.reset()
            charsetDecoder.decode(inBuffer, outBuffer, false)
        }
        outBuffer.flip()
        return outBuffer.toString()
    }
    

    سپس ، هش SHA246 از nonce را به عنوان یک رشته شش ضلعی دریافت کنید:

    جاوا

    private String sha256(String s) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(s.getBytes());
        StringBuilder hash = new StringBuilder();
        for (byte c: digest) {
            hash.append(String.format("%02x", c));
        }
        return hash.toString();
    }
    

    Kotlin+KTX

    private fun sha256(s: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val digest = md.digest(s.toByteArray())
        val hash = StringBuilder()
        for (c in digest) {
            hash.append(String.format("%02x", c))
        }
        return hash.toString()
    }
    

    شما با درخواست ورود به سیستم ، هش SHA256 nonce را ارسال می کنید ، که اپل در پاسخ آن را بدون تغییر رد می کند. Firebase با هش کردن nonce اصلی و مقایسه آن با مقدار تصویب شده توسط Apple ، پاسخ را معتبر می کند.

  2. جریان ورود به سیستم Apple را با استفاده از کتابخانه OAuth یا روش دیگر آغاز کنید. اطمینان حاصل کنید که hasce nonce را به عنوان یک پارامتر در درخواست خود قرار دهید.

  3. پس از شما پاسخ اپل دریافت، دریافت شناسه نشانه از پاسخ و استفاده از آن و مقصود فعلی unhashed برای ایجاد یک AuthCredential :

    جاوا

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    

    Kotlin+KTX

    val credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build()
    
  4. احراز هویت با Firebase با استفاده از اعتبار Firebase:

    جاوا

    mAuth.signInWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
          @Override
          public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
              // User successfully signed in with Apple ID token.
              // ...
            }
          }
        });
    

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { task ->
              if (task.isSuccessful) {
                // User successfully signed in with Apple ID token.
                // ...
              }
          }
    

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

مراحل بعدی

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

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

  • در خود پایگاه فایربیس بیدرنگ و ابر ذخیره سازی قوانین امنیتی ، شما می توانید دریافت امضا در شناسه کاربری منحصر به فرد کاربر را از auth متغیر، و استفاده از آن برای کنترل آنچه داده دسترسی کاربر می تواند.

شما می توانید اجازه به کاربران برای ورود به سیستم برنامه خود را با استفاده از ارائه دهندگان تأیید هویت چندگانه توسط ارتباط تایید اعتبار ارائه دهنده به یک حساب کاربری موجود.

برای خروج از سیستم یک کاربر، پاسخ signOut :

جاوا

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()