اصالت‌سنجی بااستفاده از OpenID Connect در پلاتفرم‌های Apple

اگر به Firebase Authentication with Identity Platform ارتقا داده‌اید، می‌توانید کاربران خود را بااستفاده از ارائه‌دهنده سازگار با OpenID Connect (OIDC) موردنظرتان با Firebase اصالت‌سنجی کنید. این کار امکان استفاده از ارائه‌دهندگان هویت را که به‌طور بومی توسط Firebase پشتیبانی نمی‌شوند فراهم می‌کند.

قبل از شروع

برای ورود به سیستم کاربران بااستفاده از ارائه‌دهنده OIDC، ابتدا باید اطلاعاتی از ارائه‌دهنده جمع‌آوری کنید:

  • شناسه کارخواه: رشته‌ای منحصربه‌فرد برای ارائه‌دهنده که برنامه شما را شناسایی می‌کند. ارائه‌دهنده شما ممکن است برای هر پلاتفرمی که پشتیبانی می‌کنید، شناسه کارخواه متفاوتی به شما اختصاص دهد. این یکی از مقادیر ادعای aud در نشان‌های شناسایی صادرشده توسط ارائه‌دهنده شما است.

  • رمز کارخواه: رشته رمزی که ارائه‌دهنده برای تأیید مالکیت شناسه کارخواه استفاده می‌کند. برای هر شناسه کارخواه، به رمز کارخواه منطبق نیاز دارید. (این مقدار فقط درصورتی الزامی است که از جریان کد اصالت‌سنجی استفاده می‌کنید که به‌شدت توصیه می‌شود.)

  • صادرکننده: رشته‌ای که ارائه‌دهنده شما را شناسایی می‌کند. این مقدار باید نشانی وبی باشد که وقتی به /.well-known/openid-configuration اضافه می‌شود، مکان سند اکتشاف OIDC ارائه‌دهنده را نشان دهد. برای مثال، اگر صادرکننده https://auth.example.com است، سند شناسایی باید در https://auth.example.com/.well-known/openid-configuration دردسترس باشد.

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

  1. ‫Firebase را به پروژه iOS خود اضافه کنید.

  2. اگر به Firebase Authentication with Identity Platform ارتقا نداده‌اید، این کار را انجام دهید. اصالت‌سنجی OpenID Connect فقط در پروژه‌های ارتقایافته دردسترس است.

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

  4. در برگه روش ورود به سیستم، روی افزودن ارائه‌دهنده جدید کلیک کنید، و سپس روی OpenID Connect کلیک کنید.

  5. انتخاب کنید که از جریان کد مجوز یا جریان اعطای ضمنی استفاده خواهید کرد.

    اگر ارائه‌دهنده شما از جریان کد پشتیبانی می‌کند، همیشه باید از جریان کد استفاده کنید. جریان ضمنی امنیت کمتری دارد و استفاده از آن به‌شدت توصیه نمی‌شود.

  6. نامی برای این ارائه‌دهنده انتخاب کنید. شناسه ارائه‌دهنده تولیدشده را یادداشت کنید: چیزی شبیه oidc.example-provider. وقتی کد ورود به سیستم را به برنامه‌تان اضافه می‌کنید به این شناسه نیاز خواهید داشت.

  7. شناسه کارخواه و رمز کارخواه، و رشته صادرکننده ارائه‌دهنده را مشخص کنید. این مقادیر باید دقیقاً با مقادیری که ارائه‌دهنده به شما اختصاص داده است مطابقت داشته باشد.

  8. تغییرات خود را ذخیره کنید.

مدیریت جریان ورود به سیستم با «کیت توسعه نرم‌افزار Firebase»

آسان‌ترین راه برای اصالت‌سنجی کاربران با Firebase بااستفاده از ارائه‌دهنده OIDC این است که کل جریان ورود به سیستم را با «کیت توسعه نرم‌افزار Firebase» مدیریت کنید.

برای مدیریت جریان ورود به سیستم با «کیت توسعه نرم‌افزار پلاتفرم‌های Firebase Apple»، این مراحل را دنبال کنید:

  1. طرح‌های نشانی وب سفارشی را به پروژه Xcode خود اضافه کنید:

    1. پیکربندی پروژه را باز کنید: روی نام پروژه در نمای درختی سمت راست دوکلیک کنید. برنامه‌تان را از بخش هدف‌ها انتخاب کنید، سپس برگه اطلاعات را انتخاب کنید و بخش انواع نشانی وب را ازهم باز کنید.
    2. روی دکمه + کلیک کنید و «شناسه برنامه کدبندی‌شده» خود را به‌عنوان طرح نشانی وب اضافه کنید. بقیه فیلدها را خالی بگذارید.

      می‌توانید «شناسه برنامه کدبندی‌شده» را در کنسول Firebase پیدا کنید: به تنظیمات > برگه کلی بروید، سپس به بخش برنامه‌های شما پیمایش کنید تا جزئیات مربوط به برنامه iOS خود را ببینید.

      وقتی تکمیل شد، پیکربندی شما باید چیزی شبیه به موارد زیر باشد (اما با مقادیر ویژه برنامه شما):

      نماگرفت میانای راه‌اندازی طرح‌واره نشانی وب سفارشی Xcode
  2. بااستفاده از شناسه ارائه‌دهنده‌ای که در کنسول Firebase دریافت کرده‌اید، نمونه‌ای از OAuthProvider ایجاد کنید.

    Swift

    var provider = OAuthProvider(providerID: "oidc.example-provider")
    

    Objective-C

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. اختیاری: پارامترهای سفارشی OAuth اضافی را که می‌خواهید با درخواست OAuth ارسال کنید مشخص کنید.

    Swift

    provider.customParameters = [
      "login_hint": "user@example.com"
    ]
    

    Objective-C

    [provider setCustomParameters:@{@"login_hint": @"user@example.com"}];
    

    برای اطلاع از پارامترهایی که ارائه‌دهنده‌تان پشتیبانی می‌کند، با او تماس بگیرید. توجه داشته باشید که نمی‌توانید پارامترهای الزامی Firebase را با setCustomParameters ارسال کنید. این پارامترها عبارت‌اند از client_id، response_type، redirect_uri، state، scope، و response_mode.

  4. اختیاری: دامنه‌های OAuth 2.0 اضافی را فراتر از نمایه پایه که می‌خواهید از ارائه‌دهنده اصالت‌سنجی درخواست کنید مشخص کنید.

    Swift

    provider.scopes = ["mail.read", "calendars.read"]
    

    Objective-C

    [provider setScopes:@[@"mail.read", @"calendars.read"]];
    

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

  5. اختیاری: اگر می‌خواهید نحوه ارائه SFSafariViewController یا UIWebView توسط برنامه‌تان را هنگام نمایش reCAPTCHA به کاربر سفارشی‌سازی کنید، کلاس سفارشی‌ای ایجاد کنید که با پروتکل AuthUIDelegate سازگار باشد.

  6. بااستفاده از شیء ارائه‌دهنده OAuth، با Firebase اصالت‌سنجی کنید.

    Swift

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    provider.getCredentialWith(nil) { credential, error in
      if error != nil {
        // Handle error.
      }
      if credential != nil {
        Auth().signIn(with: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
      }
    }
    

    Objective-C

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    [provider getCredentialWithUIDelegate:nil
                                completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
      if (error) {
        // Handle error.
      }
      if (credential) {
        [[FIRAuth auth] signInWithCredential:credential
                                  completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
          if (error) {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
      }
    }];
    
  7. اگرچه مثال‌های بالا بر جریان‌های ورود به سیستم تمرکز دارند، شما همچنین می‌توانید بااستفاده از linkWithCredential ارائه‌دهنده OIDC را به کاربر موجود پیوند دهید. برای مثال، می‌توانید چندین ارائه‌دهنده را به یک کاربر پیوند دهید و به او اجازه دهید با هرکدام از آن‌ها وارد سیستم شود.

    Swift

    Auth().currentUser.link(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        linkWithCredential:credential
                completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    
  8. از همین الگو می‌توان با reauthenticateWithCredential استفاده کرد که می‌توان از آن برای بازیابی اطلاعات اعتباری جدید برای عملیات حساس که نیاز به ورود به سیستم اخیر دارند استفاده کرد.

    Swift

    Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        reauthenticateWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    

جریان ورود به سیستم را به‌صورت دستی مدیریت کنید

اگر قبلاً جریان ورود به سیستم OpenID Connect را در برنامه‌تان پیاده‌سازی کرده‌اید، می‌توانید از نشانه ID مستقیماً برای درستی‌سنجی با Firebase استفاده کنید:

Swift

let credential = OAuthProvider.credential(
    withProviderID: "oidc.example-provider",  // As registered in Firebase console.
    idToken: idToken,  // ID token from OpenID Connect flow.
    rawNonce: nil
)
Auth.auth().signIn(with: credential) { authResult, error in
    if error {
        // Handle error.
        return
    }
    // User is signed in.
    // IdP data available in authResult?.additionalUserInfo?.profile
}

Objective-C

FIROAuthCredential *credential =
    [FIROAuthProvider credentialWithProviderID:@"oidc.example-provider"  // As registered in Firebase console.
                                       IDToken:idToken  // ID token from OpenID Connect flow.
                                      rawNonce:nil];
[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                      NSError * _Nullable error) {
    if (error != nil) {
        // Handle error.
        return;
    }
    // User is signed in.
    // IdP data available in authResult.additionalUserInfo.profile
}];

مراحل بعدی

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

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

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

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

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

Swift

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

Objective-C

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

همچنین ممکن است بخواهید کد مدیریت خطا را برای طیف کامل خطاهای اصالت‌سنجی اضافه کنید. مدیریت خطاها را ببینید.