احراز هویت با استفاده از OpenID Connect در پلتفرم های اپل

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

قبل از شروع

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

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

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

  • صادرکننده : رشته ای که ارائه دهنده شما را مشخص می کند. این مقدار باید یک URL باشد که وقتی با /.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 ، روی افزودن ارائه دهنده جدید کلیک کنید و سپس روی OpenID Connect کلیک کنید.

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

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

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

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

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

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

ساده‌ترین راه برای احراز هویت کاربران با Firebase با استفاده از ارائه‌دهنده OIDC، مدیریت کل جریان ورود به سیستم با Firebase SDK است.

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

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

    1. پیکربندی پروژه خود را باز کنید: روی نام پروژه در نمای درختی سمت چپ دوبار کلیک کنید. برنامه خود را از بخش TARGETS انتخاب کنید، سپس برگه Info را انتخاب کنید و بخش URL Types را گسترش دهید.
    2. روی دکمه + کلیک کنید و شناسه برنامه رمزگذاری شده خود را به عنوان یک طرح URL اضافه کنید. می توانید شناسه برنامه رمزگذاری شده خود را در صفحه تنظیمات عمومی کنسول Firebase، در بخش برنامه iOS خود بیابید. فیلدهای دیگر را خالی بگذارید.

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

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

    سویفت

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

    هدف-C

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

    سویفت

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

    هدف-C

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

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

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

    سویفت

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

    هدف-C

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

    با ارائه دهنده خود برای دامنه هایی که پشتیبانی می کند تماس بگیرید.

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

  6. با استفاده از شی ارائه دهنده OAuth با Firebase احراز هویت کنید.

    سویفت

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

    هدف-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 را به یک کاربر موجود پیوند دهید. برای مثال، می‌توانید چندین ارائه‌دهنده را به یک کاربر پیوند دهید و به آنها اجازه دهید با هر یک از آنها وارد سیستم شوند.

    سویفت

    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
    }
    

    هدف-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 استفاده کرد که می تواند برای بازیابی اعتبارنامه های جدید برای عملیات حساسی که نیاز به ورود اخیر دارند استفاده شود.

    سویفت

    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
    }
    

    هدف-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 استفاده کنید:

سویفت

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
}

هدف-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: .

سویفت

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

هدف-C

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

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