Android पर Apple का उपयोग करके प्रमाणित करें

आप अपने उपयोगकर्ताओं को एंड-टू-एंड OAuth 2.0 साइन-इन प्रवाह करने के लिए Firebase SDK का उपयोग करके उनके Apple ID का उपयोग करके Firebase के साथ प्रमाणित करने दे सकते हैं।

शुरू करने से पहले

Apple का उपयोग करने वाले उपयोगकर्ताओं में साइन इन करने के लिए, पहले Apple की डेवलपर साइट पर Apple के साथ साइन इन करें, फिर अपने Firebase प्रोजेक्ट के लिए Apple को साइन-इन प्रदाता के रूप में सक्षम करें।

Apple डेवलपर प्रोग्राम में शामिल हों

Apple के साथ साइन इन केवल Apple डेवलपर प्रोग्राम के सदस्यों द्वारा कॉन्फ़िगर किया जा सकता है।

Apple के साथ साइन इन कॉन्फ़िगर करें

Apple डेवलपर साइट पर, निम्न कार्य करें:

  1. वेब के लिए Apple के साथ साइन इन कॉन्फ़िगर करें के पहले खंड में बताए अनुसार अपनी वेबसाइट को अपने ऐप से संबद्ध करें। संकेत दिए जाने पर, निम्न URL को वापसी URL के रूप में पंजीकृत करें:

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

    आप Firebase कंसोल सेटिंग पेज पर अपना Firebase प्रोजेक्ट आईडी प्राप्त कर सकते हैं।

    जब आप काम पूरा कर लें, तो अपनी नई सेवा आईडी पर ध्यान दें, जिसकी आपको अगले भाग में आवश्यकता होगी।

  2. Apple निजी कुंजी के साथ एक साइन इन बनाएँ । आपको अगले भाग में अपनी नई निजी कुंजी और कुंजी आईडी की आवश्यकता होगी।
  3. यदि आप फायरबेस ऑथेंटिकेशन की किसी भी सुविधा का उपयोग करते हैं जो उपयोगकर्ताओं को ईमेल भेजती है, जिसमें ईमेल लिंक साइन-इन, ईमेल पता सत्यापन, खाता परिवर्तन निरस्तीकरण, और अन्य शामिल हैं, तो Apple निजी ईमेल रिले सेवा को कॉन्फ़िगर करें और noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (या आपका अनुकूलित ईमेल टेम्प्लेट डोमेन) ताकि Apple Firebase प्रमाणीकरण द्वारा भेजे गए ईमेल को अज्ञात Apple ईमेल पतों पर रिले कर सके।

साइन-इन प्रदाता के रूप में Apple को सक्षम करें

  1. अपने Android प्रोजेक्ट में Firebase जोड़ें । जब आप अपने ऐप को फायरबेस कंसोल में सेट करते हैं तो अपने ऐप के SHA-1 हस्ताक्षर को पंजीकृत करना सुनिश्चित करें।
  2. Firebase कंसोल में, प्रामाणिक अनुभाग खोलें। साइन इन विधि टैब पर, Apple प्रदाता को सक्षम करें। पिछले अनुभाग में आपके द्वारा बनाई गई सेवा आईडी निर्दिष्ट करें। साथ ही, OAuth कोड फ़्लो कॉन्फ़िगरेशन अनुभाग में, अपनी Apple टीम ID और निजी कुंजी और कुंजी ID निर्दिष्ट करें जिसे आपने पिछले अनुभाग में बनाया था।

Apple की अनाम डेटा आवश्यकताओं का अनुपालन करें

Apple के साथ साइन इन करें उपयोगकर्ताओं को साइन इन करते समय, उनके ईमेल पते सहित, उनके डेटा को गुमनाम करने का विकल्प देता है। इस विकल्प को चुनने वाले उपयोगकर्ताओं के ईमेल पते privaterelay.appleid.com डोमेन के साथ होते हैं। जब आप अपने ऐप में Apple के साथ साइन इन का उपयोग करते हैं, तो आपको इन अज्ञात Apple ID के संबंध में Apple की किसी भी लागू डेवलपर नीतियों या शर्तों का पालन करना होगा।

इसमें किसी अज्ञात Apple ID के साथ सीधे तौर पर पहचान करने वाली व्यक्तिगत जानकारी को संबद्ध करने से पहले आवश्यक उपयोगकर्ता सहमति प्राप्त करना शामिल है। फायरबेस प्रमाणीकरण का उपयोग करते समय, इसमें निम्नलिखित क्रियाएं शामिल हो सकती हैं:

  • एक ईमेल पते को एक अनाम Apple ID या इसके विपरीत लिंक करें।
  • फ़ोन नंबर को किसी अज्ञात Apple ID या इसके विपरीत लिंक करें
  • एक गैर-अनाम सामाजिक क्रेडेंशियल (Facebook, Google, आदि) को एक अज्ञात Apple ID या इसके विपरीत लिंक करें।

उपरोक्त सूची संपूर्ण नहीं है। यह सुनिश्चित करने के लिए कि आपका ऐप Apple की आवश्यकताओं को पूरा करता है, अपने डेवलपर खाते के सदस्यता अनुभाग में Apple डेवलपर प्रोग्राम लाइसेंस अनुबंध देखें।

फायरबेस एसडीके के साथ साइन-इन प्रवाह को संभालें

Android पर, अपने उपयोगकर्ताओं को उनके Apple खातों का उपयोग करके Firebase के साथ प्रमाणित करने का सबसे आसान तरीका है, Firebase Android SDK के साथ संपूर्ण साइन-इन प्रवाह को संभालना।

फायरबेस एंड्रॉइड एसडीके के साथ साइन-इन प्रवाह को संभालने के लिए, इन चरणों का पालन करें:

  1. apple.com प्रदाता आईडी के साथ इसके बिल्डर का उपयोग करके OAuthProvider का एक उदाहरण बनाएं:

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    
  2. वैकल्पिक: डिफ़ॉल्ट से परे अतिरिक्त OAuth 2.0 स्कोप निर्दिष्ट करें जिसे आप प्रमाणीकरण प्रदाता से अनुरोध करना चाहते हैं।

    Kotlin+KTX

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

    Java

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

    डिफ़ॉल्ट रूप से, जब प्रति ईमेल पता एक खाता सक्षम होता है, तो Firebase ईमेल और नाम के दायरे का अनुरोध करता है। यदि आप इस सेटिंग को प्रति ईमेल पते पर एकाधिक खातों में बदलते हैं, तो Firebase तब तक Apple से किसी भी दायरे का अनुरोध नहीं करता है जब तक कि आप उन्हें निर्दिष्ट नहीं करते।

  3. वैकल्पिक: यदि आप Apple की साइन-इन स्क्रीन को अंग्रेजी के अलावा किसी अन्य भाषा में प्रदर्शित करना चाहते हैं, तो locale पैरामीटर सेट करें। समर्थित स्थानों के लिए Apple डॉक्स के साथ साइन इन देखें।

    Kotlin+KTX

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

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    
  4. OAuth प्रदाता ऑब्जेक्ट का उपयोग करके फायरबेस के साथ प्रमाणित करें। ध्यान दें कि अन्य FirebaseAuth संचालन के विपरीत, यह कस्टम क्रोम टैब खोलकर आपके UI को नियंत्रित करेगा। नतीजतन, अपनी गतिविधि को OnSuccessListener और OnFailureListener में संदर्भित न करें जो आप संलग्न करते हैं क्योंकि ऑपरेशन UI शुरू होने पर वे तुरंत अलग हो जाएंगे।

    आपको पहले यह जांचना चाहिए कि क्या आपको पहले ही कोई प्रतिक्रिया मिल चुकी है। इस विधि से साइन इन करना आपकी गतिविधि को पृष्ठभूमि में रखता है, जिसका अर्थ है कि साइन इन प्रवाह के दौरान सिस्टम द्वारा इसे पुनः प्राप्त किया जा सकता है। यह सुनिश्चित करने के लिए कि ऐसा होने पर आप उपयोगकर्ता को फिर से प्रयास न करने दें, आपको यह जांचना चाहिए कि क्या कोई परिणाम पहले से मौजूद है।

    यह जांचने के लिए कि क्या कोई लंबित परिणाम है, getPendingAuthResult() पर कॉल करें:

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

    Java

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

    यदि कोई परिणाम लंबित नहीं है, तो startActivityForSignInWithProvider() पर कॉल करके साइन इन प्रवाह प्रारंभ करें:

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

    Java

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

    फायरबेस ऑथ द्वारा समर्थित अन्य प्रदाताओं के विपरीत, ऐप्पल फोटो यूआरएल प्रदान नहीं करता है।

    साथ ही, जब उपयोगकर्ता अपने ईमेल को ऐप के साथ साझा नहीं करना चुनता है, तो Apple उस उपयोगकर्ता के लिए एक अद्वितीय ईमेल पता प्रदान करता है (फ़ॉर्म xyz@privaterelay.appleid.com ), जिसे वह आपके ऐप के साथ साझा करता है। यदि आपने निजी ईमेल रिले सेवा को कॉन्फ़िगर किया है, तो Apple उपयोगकर्ता के वास्तविक ईमेल पते पर गुमनाम पते पर भेजे गए ईमेल को अग्रेषित करता है।

    जब उपयोगकर्ता पहली बार साइन इन करता है तो Apple केवल ऐप के साथ डिस्प्ले नाम जैसी उपयोगकर्ता जानकारी साझा करता है। आमतौर पर, Firebase उपयोगकर्ता द्वारा पहली बार Apple के साथ साइन इन करने पर डिस्प्ले नाम को स्टोर करता है, जिसे आप getCurrentUser().getDisplayName() से प्राप्त कर सकते हैं। हालाँकि, यदि आपने पहले Apple का उपयोग किसी उपयोगकर्ता को ऐप में बिना Firebase के साइन इन करने के लिए किया था, तो Apple उपयोगकर्ता के प्रदर्शन नाम के साथ Firebase प्रदान नहीं करेगा।

प्रमाणीकरण और खाता लिंकिंग

उसी पैटर्न का उपयोग startActivityForReauthenticateWithProvider() के साथ किया जा सकता है जिसका उपयोग आप संवेदनशील संचालन के लिए एक नया क्रेडेंशियल प्राप्त करने के लिए कर सकते हैं जिसके लिए हाल ही में साइन-इन की आवश्यकता होती है:

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

Java

// 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.
          }
        });

और, आप विभिन्न पहचान प्रदाताओं को मौजूदा खातों से लिंक करने के लिए linkWithCredential() का उपयोग कर सकते हैं।

ध्यान दें कि Apple के लिए आवश्यक है कि आप उपयोगकर्ताओं के Apple खातों को अन्य डेटा से लिंक करने से पहले उनकी स्पष्ट सहमति लें।

उदाहरण के लिए, किसी Facebook खाते को वर्तमान Firebase खाते से लिंक करने के लिए, उस एक्सेस टोकन का उपयोग करें जो आपको उपयोगकर्ता को 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.
        }
      });

Java

// 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.
        }
      }
    });

उन्नत: साइन-इन प्रवाह को मैन्युअल रूप से प्रबंधित करें

आप या तो Apple साइन-इन JS SDK का उपयोग करके, मैन्युअल रूप से OAuth प्रवाह का निर्माण करके या AppAuth जैसी OAuth लाइब्रेरी का उपयोग करके साइन-इन प्रवाह को प्रबंधित करके Apple खाते का उपयोग करके Firebase के साथ प्रमाणित कर सकते हैं।

  1. प्रत्येक साइन-इन अनुरोध के लिए, एक यादृच्छिक स्ट्रिंग उत्पन्न करें—एक "नॉन्स"—जिसका उपयोग आप यह सुनिश्चित करने के लिए करेंगे कि आपको प्राप्त होने वाला आईडी टोकन विशेष रूप से आपके ऐप के प्रमाणीकरण अनुरोध के जवाब में प्रदान किया गया था। रीप्ले हमलों को रोकने के लिए यह कदम महत्वपूर्ण है।

    आप Android पर SecureRandom के साथ एक क्रिप्टोग्राफ़िक रूप से सुरक्षित नॉन जनरेट कर सकते हैं, जैसा कि निम्न उदाहरण में दिखाया गया है:

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

    Java

    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();
    }
    

    फिर, हेक्स स्ट्रिंग के रूप में नॉन का SHA246 हैश प्राप्त करें:

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

    Java

    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();
    }
    

    आप अपने साइन-इन अनुरोध के साथ नॉन का SHA256 हैश भेजेंगे, जिसे प्रतिक्रिया में Apple अपरिवर्तित पारित करेगा। फायरबेस मूल नॉन को हैश करके और Apple द्वारा पास किए गए मान से तुलना करके प्रतिक्रिया को मान्य करता है।

  2. अपनी OAuth लाइब्रेरी या अन्य विधि का उपयोग करके Apple के साइन-इन प्रवाह को आरंभ करें। अपने अनुरोध में एक पैरामीटर के रूप में हैशेड नॉन को शामिल करना सुनिश्चित करें।

  3. आपके द्वारा Apple की प्रतिक्रिया प्राप्त करने के बाद, प्रतिक्रिया से ID टोकन प्राप्त करें और AuthCredential बनाने के लिए इसका और बिना हैश किए हुए नॉन का उपयोग करें:

    Kotlin+KTX

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

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    
  4. Firebase क्रेडेंशियल का उपयोग करके Firebase के साथ प्रमाणित करें:

    Kotlin+KTX

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

    Java

    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.
              // ...
            }
          }
        });
    

यदि साइन इन getCurrentUser signInWithCredential का उपयोग कर सकते हैं।

अगले कदम

उपयोगकर्ता द्वारा पहली बार साइन इन करने के बाद, एक नया उपयोगकर्ता खाता बनाया जाता है और क्रेडेंशियल्स से लिंक किया जाता है—यानी, उपयोगकर्ता नाम और पासवर्ड, फ़ोन नंबर, या प्रमाणीकरण प्रदाता जानकारी—जिसके साथ उपयोगकर्ता ने साइन इन किया है। यह नया खाता आपके फायरबेस प्रोजेक्ट के हिस्से के रूप में संग्रहीत है, और उपयोगकर्ता द्वारा साइन इन किए जाने पर ध्यान दिए बिना, आपके प्रोजेक्ट में प्रत्येक ऐप में उपयोगकर्ता की पहचान करने के लिए इसका उपयोग किया जा सकता है।

  • अपने ऐप्लिकेशन में, आप FirebaseUser ऑब्जेक्ट से उपयोगकर्ता की मूल प्रोफ़ाइल जानकारी प्राप्त कर सकते हैं। उपयोगकर्ता प्रबंधित करें देखें।

  • आपके फायरबेस रीयलटाइम डेटाबेस और क्लाउड स्टोरेज सुरक्षा नियमों में, आप auth चर से साइन-इन किए गए उपयोगकर्ता की विशिष्ट उपयोगकर्ता आईडी प्राप्त कर सकते हैं, और इसका उपयोग यह नियंत्रित करने के लिए कर सकते हैं कि उपयोगकर्ता किस डेटा तक पहुंच सकता है।

आप प्रमाणीकरण प्रदाता क्रेडेंशियल्स को किसी मौजूदा उपयोगकर्ता खाते से लिंक करके उपयोगकर्ताओं को एकाधिक प्रमाणीकरण प्रदाताओं का उपयोग करके अपने ऐप में साइन इन करने की अनुमति दे सकते हैं।

किसी उपयोगकर्ता को साइन आउट करने के लिए, signOut को कॉल करें:

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();