আইওএস এ অ্যাপল ব্যবহার করে প্রমাণীকরণ করুন

আপনি আপনার ব্যবহারকারীদের তাদের অ্যাপল আইডি ব্যবহার করে Firebase SDK ব্যবহার করে এন্ড-টু-এন্ড OAuth 2.0 সাইন-ইন ফ্লো চালাতে পারেন।

তুমি শুরু করার আগে

অ্যাপল ব্যবহার করে ব্যবহারকারীদের সাইন ইন করতে প্রথমে অ্যাপলের ডেভেলপার সাইটে অ্যাপলের সাথে সাইন ইন কনফিগার করুন, তারপর অ্যাপলকে আপনার ফায়ারবেস প্রকল্পের জন্য একটি সাইন-ইন প্রদানকারী হিসেবে সক্ষম করুন।

অ্যাপল ডেভেলপার প্রোগ্রামে যোগ দিন

সাইন ইন অ্যাপল শুধুমাত্র সদস্য কনফিগার করা যেতে পারে অ্যাপল বিকাশকারী প্রোগ্রাম

অ্যাপলের সাথে সাইন ইন কনফিগার করুন

  1. আপনার অ্যাপের জন্য অ্যাপল দিয়ে সাইন ইন সক্ষম করুন সার্টিফিকেট, শনাক্তকারীগণ & প্রোফাইল অ্যাপলের ডেভেলপার সাইটের পৃষ্ঠা।
  2. আপনি ইমেইল লিঙ্ক সাইন-ইন, ইমেল ঠিকানা যাচাই, অ্যাকাউন্ট পরিবর্তন প্রত্যাহার, এবং অন্যদের সহ Firebase প্রমাণীকরণ এর বৈশিষ্ট্য ব্যবহারকারীরা আর কোনো ইমেল পাঠাতে, কোন ব্যবহার করেন তাহলে কনফিগার অ্যাপল ব্যক্তিগত ইমেইলের রিলে সেবা এবং নিবন্ধন noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (অথবা আপনার কাস্টমাইজড ইমেইল টেমপ্লেট ডোমেইন) যাতে অ্যাপল ফায়ারবেস প্রমাণীকরণ দ্বারা প্রেরিত ইমেলগুলি বেনামী অ্যাপল ইমেল ঠিকানায় রিলে করতে পারে।

অ্যাপলকে সাইন-ইন প্রদানকারী হিসেবে সক্ষম করুন

  1. আপনার iOS প্রকল্পে Firebase যোগ করুন । ফায়ারবেস কনসোলে আপনার অ্যাপ সেট আপ করার সময় আপনার অ্যাপের বান্ডেল আইডি নিবন্ধন করতে ভুলবেন না।
  2. ইন Firebase কনসোল , প্রমাণীকরণ অধ্যায় খুলুন। পদ্ধতি ট্যাবে সাইন অন অ্যাপল প্রদানকারী সক্রিয় করুন। যদি আপনি শুধুমাত্র একটি iOS অ্যাপে অ্যাপলের সাথে সাইন ইন ব্যবহার করেন, তাহলে আপনি পরিষেবা আইডি, অ্যাপল টিম আইডি, প্রাইভেট কী এবং কী আইডি ক্ষেত্রগুলি খালি রাখতে পারেন।

অ্যাপল বেনামী ডেটা প্রয়োজনীয়তা মেনে চলুন

এই অপশনটি নির্বাচন সঙ্গে অ্যাপল ব্যবহারকারীদের তাদের ইমেল ঠিকানা সহ সেগুলির ডেটা, anonymizing সাইন ইন করার সময় বিকল্প দেয় সাইন ইন করুন। ব্যবহারকারীরা ডোমেনের সাথে ইমেল ঠিকানা রয়েছে privaterelay.appleid.com । যখন আপনি আপনার অ্যাপে অ্যাপলের সাথে সাইন ইন ব্যবহার করেন, তখন আপনাকে এই বেনামী অ্যাপল আইডি সংক্রান্ত অ্যাপলের কোন প্রযোজ্য বিকাশকারী নীতি বা শর্তাবলী মেনে চলতে হবে।

এর মধ্যে আপনি কোনো পরিচয়হীন অ্যাপল আইডির সঙ্গে সরাসরি পরিচিত কোনো ব্যক্তিগত তথ্য সংযুক্ত করার আগে প্রয়োজনীয় ব্যবহারকারীর সম্মতি পাওয়া অন্তর্ভুক্ত করে। Firebase প্রমাণীকরণ ব্যবহার করার সময়, এতে নিম্নলিখিত ক্রিয়াগুলি অন্তর্ভুক্ত থাকতে পারে:

  • একটি বেনামী অ্যাপল আইডিতে একটি ইমেইল ঠিকানা লিঙ্ক করুন বা বিপরীতভাবে।
  • একটি নাম্বারবিহীন অ্যাপল আইডিতে একটি ফোন নম্বর লিঙ্ক করুন অথবা উল্টো
  • একটি অজ্ঞাতনামা সামাজিক পরিচয়পত্র (ফেসবুক, গুগল, ইত্যাদি) একটি বেনামী অ্যাপল আইডি বা বিপরীতভাবে লিঙ্ক করুন।

উপরের তালিকায় সম্পূর্ণ নয়। আপনার অ্যাপল অ্যাপলের প্রয়োজনীয়তা পূরণ করে তা নিশ্চিত করতে আপনার ডেভেলপার অ্যাকাউন্টের সদস্যপদ বিভাগে অ্যাপল ডেভেলপার প্রোগ্রাম লাইসেন্স চুক্তিটি পড়ুন।

অ্যাপলের সাথে সাইন ইন করুন এবং ফায়ারবেস দিয়ে প্রমাণীকরণ করুন

একটি আপেল অ্যাকাউন্ট সহ প্রমাণীকরণ করতে, প্রথমে তাদের অ্যাপল করার জন্য ব্যবহারকারী সাইন ইন ব্যবহার করে অ্যাকাউন্ট অ্যাপলের AuthenticationServices ফ্রেমওয়ার্ক , এবং তারপর আইডি অ্যাপলের প্রতিক্রিয়া থেকে টোকেনটি ব্যবহার একটি Firebase তৈরি করতে AuthCredential বস্তু:

  1. প্রতিটি সাইন-ইন অনুরোধের জন্য, একটি এলোমেলো স্ট্রিং জেনারেট করুন-একটি "ননস"-যা আপনি নিশ্চিত করতে ব্যবহার করবেন যে আইডি টোকেনটি আপনার অ্যাপের প্রমাণীকরণের অনুরোধের জবাবে বিশেষভাবে মঞ্জুর করা হয়েছে। রিপ্লে আক্রমণ প্রতিরোধের জন্য এই পদক্ষেপটি গুরুত্বপূর্ণ।

    আপনার সাথে iOS এ একটা ক্রিপ্টোগ্রাফি নিরাপদ আপাতত তৈরি করতে পারেন SecRandomCopyBytes(_:_:_) , নিম্নলিখিত উদাহরণে হিসাবে:

    সুইফট

    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    private func randomNonceString(length: Int = 32) -> String {
      precondition(length > 0)
      let charset: Array<Character> =
          Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
      var result = ""
      var remainingLength = length
    
      while remainingLength > 0 {
        let randoms: [UInt8] = (0 ..< 16).map { _ in
          var random: UInt8 = 0
          let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
          if errorCode != errSecSuccess {
            fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
          }
          return random
        }
    
        randoms.forEach { random in
          if remainingLength == 0 {
            return
          }
    
          if random < charset.count {
            result.append(charset[Int(random)])
            remainingLength -= 1
          }
        }
      }
    
      return result
    }
    

    উদ্দেশ্য গ

    - (NSString *)randomNonce:(NSInteger)length {
      NSAssert(length > 0, @"Expected nonce to have positive length");
      NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
      NSMutableString *result = [NSMutableString string];
      NSInteger remainingLength = length;
    
      while (remainingLength > 0) {
        NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
        for (NSInteger i = 0; i < 16; i++) {
          uint8_t random = 0;
          int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
          NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);
    
          [randoms addObject:@(random)];
        }
    
        for (NSNumber *random in randoms) {
          if (remainingLength == 0) {
            break;
          }
    
          if (random.unsignedIntValue < characterSet.length) {
            unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
            [result appendFormat:@"%C", character];
            remainingLength--;
          }
        }
      }
    
      return result;
    }
    

    আপনি আপনার সাইন-ইন রিকোয়েস্ট সহ ননস এর SHA256 হ্যাশ পাঠাবেন, যা অ্যাপল প্রতিক্রিয়াতে অপরিবর্তিত থাকবে। ফায়ারবেস আসল ননস হ্যাশ করে এবং অ্যাপল দ্বারা প্রদত্ত মূল্যের সাথে তুলনা করে প্রতিক্রিয়াটি যাচাই করে।

  2. অ্যাপলের সাইন-ইন প্রবাহ শুরু করুন, আপনার অনুরোধ সহ ননস এর SHA256 হ্যাশ এবং প্রতিনিধি শ্রেণী যা অ্যাপলের প্রতিক্রিয়া পরিচালনা করবে (পরবর্তী ধাপ দেখুন):

    সুইফট

    import CryptoKit
    
    // Unhashed nonce.
    fileprivate var currentNonce: String?
    
    @available(iOS 13, *)
    func startSignInWithAppleFlow() {
      let nonce = randomNonceString()
      currentNonce = nonce
      let appleIDProvider = ASAuthorizationAppleIDProvider()
      let request = appleIDProvider.createRequest()
      request.requestedScopes = [.fullName, .email]
      request.nonce = sha256(nonce)
    
      let authorizationController = ASAuthorizationController(authorizationRequests: [request])
      authorizationController.delegate = self
      authorizationController.presentationContextProvider = self
      authorizationController.performRequests()
    }
    
    @available(iOS 13, *)
    private func sha256(_ input: String) -> String {
      let inputData = Data(input.utf8)
      let hashedData = SHA256.hash(data: inputData)
      let hashString = hashedData.compactMap {
        return String(format: "%02x", $0)
      }.joined()
    
      return hashString
    }
    

    উদ্দেশ্য গ

    @import CommonCrypto;
    
    - (void)startSignInWithAppleFlow {
      NSString *nonce = [self randomNonce:32];
      self.currentNonce = nonce;
      ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
      ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest];
      request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
      request.nonce = [self stringBySha256HashingString:nonce];
    
      ASAuthorizationController *authorizationController =
          [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
      authorizationController.delegate = self;
      authorizationController.presentationContextProvider = self;
      [authorizationController performRequests];
    }
    
    - (NSString *)stringBySha256HashingString:(NSString *)input {
      const char *string = [input UTF8String];
      unsigned char result[CC_SHA256_DIGEST_LENGTH];
      CC_SHA256(string, (CC_LONG)strlen(string), result);
    
      NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
      for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [hashed appendFormat:@"%02x", result[i]];
      }
      return hashed;
    }
    
  3. আপনার বাস্তবায়নের অ্যাপলের প্রতিক্রিয়া হ্যান্ডেল ASAuthorizationControllerDelegate । যদি সাইন-ইন সফল হয়, তাহলে ফায়ারবেস দিয়ে প্রমাণীকরণের জন্য অ্যাপলের প্রতিক্রিয়া থেকে আইডি টোকেনটি ব্যবহার করুন:

    সুইফট

    @available(iOS 13.0, *)
    extension MainViewController: ASAuthorizationControllerDelegate {
    
      func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
          guard let nonce = currentNonce else {
            fatalError("Invalid state: A login callback was received, but no login request was sent.")
          }
          guard let appleIDToken = appleIDCredential.identityToken else {
            print("Unable to fetch identity token")
            return
          }
          guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
            print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
            return
          }
          // Initialize a Firebase credential.
          let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                    IDToken: idTokenString,
                                                    rawNonce: nonce)
          // Sign in with Firebase.
          Auth.auth().signIn(with: credential) { (authResult, error) in
            if error {
              // Error. If error.code == .MissingOrInvalidNonce, make sure
              // you're sending the SHA256-hashed nonce as a hex string with
              // your request to Apple.
              print(error.localizedDescription)
              return
            }
            // User is signed in to Firebase with Apple.
            // ...
          }
        }
      }
    
      func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        // Handle error.
        print("Sign in with Apple errored: \(error)")
      }
    
    }
    

    উদ্দেশ্য গ

    - (void)authorizationController:(ASAuthorizationController *)controller
       didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
      if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
        NSString *rawNonce = self.currentNonce;
        NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent.");
    
        if (appleIDCredential.identityToken == nil) {
          NSLog(@"Unable to fetch identity token.");
          return;
        }
    
        NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken
                                                  encoding:NSUTF8StringEncoding];
        if (idToken == nil) {
          NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken);
        }
    
        // Initialize a Firebase credential.
        FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
                                                                            IDToken:idToken
                                                                           rawNonce:rawNonce];
    
        // Sign in with Firebase.
        [[FIRAuth auth] signInWithCredential:credential
                                  completion:^(FIRAuthDataResult * _Nullable authResult,
                                               NSError * _Nullable error) {
          if (error != nil) {
            // Error. If error.code == FIRAuthErrorCodeMissingOrInvalidNonce,
            // make sure you're sending the SHA256-hashed nonce as a hex string
            // with your request to Apple.
            return;
          }
          // Sign-in succeeded!
        }];
      }
    }
    
    - (void)authorizationController:(ASAuthorizationController *)controller
               didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
      NSLog(@"Sign in with Apple errored: %@", error);
    }
    

Firebase Auth দ্বারা সমর্থিত অন্যান্য প্রদানকারীর বিপরীতে, Apple একটি ছবির URL প্রদান করে না।

এছাড়াও, ব্যবহারকারী অ্যাপ্লিকেশন, সেই ব্যবহারকারীর (ফর্ম এর জন্য অ্যাপল বিধান একটি অনন্য ইমেল ঠিকানা দিয়ে তাদের ইমেল ভাগ করতে বেছে যখন xyz@privaterelay.appleid.com , যা এটি আপনার অ্যাপের সঙ্গে শেয়ার)। যদি আপনি ব্যক্তিগত ইমেইল রিলে পরিষেবা কনফিগার করেন, অ্যাপল ব্যবহারকারীর আসল ইমেল ঠিকানায় বেনামী ঠিকানায় পাঠানো ইমেল ফরওয়ার্ড করে।

অ্যাপল শুধুমাত্র শেয়ার ব্যবহারকারীর তথ্য প্রথমবার অ্যাপ্লিকেশনগুলির সাথে প্রদর্শন নাম হিসেবে এমন একটি ব্যবহারকারীর লক্ষণ। সাধারণত, Firebase দোকানে প্রদর্শন নাম প্রথমবার অ্যাপল, এটি দিয়ে একটি ব্যবহারকারী লক্ষণ আপনার সাথে পেতে পারেন Auth.auth().currentUser.displayName । যাইহোক, যদি আপনি আগে ফায়ারবেস ব্যবহার না করে অ্যাপে ব্যবহারকারীকে সাইন ইন করার জন্য অ্যাপল ব্যবহার করেন, তাহলে অ্যাপল ব্যবহারকারীর ডিসপ্লে নেম সহ ফায়ারবেস প্রদান করবে না।

পুনরায় প্রমাণীকরণ এবং অ্যাকাউন্ট লিঙ্কিং

একই প্যাটার্ন ব্যবহার করা যেতে পারে reauthenticateWithCredential() , যা আপনি সংবেদনশীল অপারেশন সাম্প্রতিক সাইন-ইন দরকার জন্য একটি তাজা ক্রেডেনশিয়াল পুনরুদ্ধার করতে ব্যবহার করতে পারেন:

সুইফট

// Initialize a fresh Apple credential with Firebase.
let credential = OAuthProvider.credential(
  withProviderID: "apple.com",
  IDToken: appleIdToken,
  rawNonce: rawNonce
)
// Reauthenticate current Apple user with fresh Apple credential.
Auth.auth().currentUser.reauthenticate(with: credential) { (authResult, error) in
  guard error != nil else { return }
  // Apple user successfully re-authenticated.
  // ...
}

উদ্দেশ্য গ

FIRAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com",
                                                                   IDToken:appleIdToken,
                                                                  rawNonce:rawNonce];
[[FIRAuth auth].currentUser
    reauthenticateWithCredential:credential
                      completion:^(FIRAuthDataResult * _Nullable authResult,
                                   NSError * _Nullable error) {
  if (error) {
    // Handle error.
  }
  // Apple user successfully re-authenticated.
  // ...
}];

এবং, আপনি ব্যবহার করতে পারেন linkWithCredential() বিদ্যমান অ্যাকাউন্টে বিভিন্ন পরিচিতি প্রদানকারীদের লিঙ্ক করতে।

মনে রাখবেন যে অ্যাপল আপনার অ্যাপল অ্যাকাউন্টগুলিকে অন্য ডেটার সাথে লিঙ্ক করার আগে ব্যবহারকারীদের কাছ থেকে স্পষ্ট সম্মতি পেতে চায়।

অ্যাপলের সাথে সাইন ইন করলে আপনি একটি বিদ্যমান অ্যাকাউন্টের সাথে লিঙ্ক করার জন্য একটি প্রমাণপত্রাদি পুনরায় ব্যবহার করতে পারবেন না। আপনি যদি অ্যাপল শংসাপত্রের সাথে অন্য একটি অ্যাকাউন্টে সাইন ইন লিঙ্ক করতে চান, তাহলে আপনাকে প্রথমে পুরনো সাইন ইন অ্যাপল শংসাপত্র ব্যবহার করে অ্যাকাউন্টগুলি লিঙ্ক করার চেষ্টা করতে হবে এবং তারপর একটি নতুন শংসাপত্র খুঁজে পেতে ফিরে আসা ত্রুটিটি পরীক্ষা করতে হবে। নতুন শংসাপত্র ত্রুটি অবস্থিত হবে userInfo অভিধান এবং মাধ্যমে অ্যাক্সেস করা যেতে পারে FIRAuthErrorUserInfoUpdatedCredentialKey কী।

উদাহরণস্বরূপ, বর্তমান ফায়ারবেস অ্যাকাউন্টের সাথে একটি ফেসবুক অ্যাকাউন্ট লিঙ্ক করতে, ব্যবহারকারীকে ফেসবুকে সাইন ইন করার সময় আপনি যে অ্যাক্সেস টোকেন পেয়েছেন তা ব্যবহার করুন:

সুইফট

// Initialize a Facebook credential with Firebase.
let credential = FacebookAuthProvider.credential(
  withAccessToken: AccessToken.current!.tokenString
)
// Assuming the current user is an Apple user linking a Facebook provider.
Auth.auth().currentUser.link(with: credential) { (authResult, error) in
  // Facebook credential is linked to the current Apple user.
  // The user can now sign in with Facebook or Apple to the same Firebase
  // account.
  // ...
}

উদ্দেশ্য গ

// Initialize a Facebook credential with Firebase.
FacebookAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:accessToken];
// Assuming the current user is an Apple user linking a Facebook provider.
[FIRAuth.auth linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
  // Facebook credential is linked to the current Apple user.
  // The user can now sign in with Facebook or Apple to the same Firebase
  // account.
  // ...
}];

পরবর্তী পদক্ষেপ

একজন ব্যবহারকারী প্রথমবার সাইন ইন করার পর, একটি নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করা হয় এবং শংসাপত্রগুলির সাথে সংযুক্ত করা হয় - অর্থাৎ ব্যবহারকারীর নাম এবং পাসওয়ার্ড, ফোন নম্বর, বা স্বাক্ষর প্রদানকারীর তথ্য — ব্যবহারকারী সাইন ইন করেছেন। এই নতুন অ্যাকাউন্টটি আপনার ফায়ারবেস প্রকল্পের অংশ হিসাবে সংরক্ষণ করা হয়েছে এবং ব্যবহারকারী যেভাবে সাইন ইন করুক না কেন আপনার প্রকল্পের প্রতিটি অ্যাপ জুড়ে ব্যবহারকারীকে চিহ্নিত করতে ব্যবহার করা যেতে পারে।

  • আপনার অ্যাপ্লিকেশান, আপনি থেকে ব্যবহারকারীর সাধারণ প্রোফাইল তথ্য পেতে পারেন FIRUser অবজেক্ট। দেখুন ব্যবহারকারীদের পরিচালনা

  • আপনার Firebase রিয়েলটাইম ডাটাবেস এবং ক্লাউড স্টোরেজ সিকিউরিটি রুলস , আপনি পেতে পারেন সাইন ইন থেকে ব্যবহারকারী এর অনন্য ব্যবহারকারী আইডি auth পরিবর্তনশীল, এবং এটি ব্যবহার কোন ডেটা একটি ব্যবহারকারী অ্যাক্সেস করতে পারবেন নিয়ন্ত্রন করতে পারেন।

আপনি ব্যবহারকারীদের দ্বারা একাধিক প্রমাণীকরণ প্রদানকারীর ব্যবহার করে আপনার অ্যাপ্লিকেশানে সাইন ইন করার অনুমতি দিতে পারেন একটি বিদ্যমান ব্যবহারকারীর অ্যাকাউন্টের সাথে প্রমাণীকরণ প্রদানকারী পরিচয়পত্র লিঙ্ক।

একটি ব্যবহারকারী সাইন আউট করতে, কল signOut:

সুইফট

    let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}
  

উদ্দেশ্য গ

    NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

আপনি প্রমাণীকরণের ত্রুটির সম্পূর্ণ পরিসরের জন্য ত্রুটি পরিচালনা কোড যোগ করতে চাইতে পারেন। দেখুন হাতল ত্রুটি