שילוב של Google Cloud Fraud Defense עם אפליקציות ל-iOS

אתם יכולים לשלב את Google Cloud Fraud Defense באפליקציות ל-iOS כדי להעריך אותות ממכשירי לקוח ולהגן על האינטראקציות של משתמשים בנייד מפני ניצול לרעה אוטומטי.

בגלל ההבדלים בין מכשירים ניידים מבחינת גודל המסך, הביצועים וממשקי המשתמש של האפליקציות, מבחן reCAPTCHA החזותי עם תיבת הסימון (אני לא רובוט) לא זמין באפליקציות לנייד ב-iOS. במקום זאת, אתם יכולים להטמיע אסטרטגיית אכיפה מדורגת משלכם, כמו תהליך אימות רב-שלבי, כדי לספק נתיב חלופי למימוש של תנועה חשודה.

ערכת ה-SDK משתמשת ברפלקציה ובקוד דינמי כדי לאפשר עדכון ושיפור של מערכת הזיהוי באפליקציות או בערכות SDK שכבר נפרסו. כדי למנוע הפרעה לאפליקציה, המחלקות שזמינות במערכת מוגבלות לרשימה מבוקרת בקפידה.

לפני שמתחילים

  1. מגדירים את גרסת ה-SDK המינימלית של האפליקציה ל-iOS 15 או יוצרים אפליקציה חדשה לנייד.

  2. הכנת הסביבה ל-Google Cloud Fraud Defense.

  3. יוצרים מפתח reCAPTCHA לפלטפורמת האפליקציה ל-iOS.

    לחלופין, אתם יכולים להעתיק את המזהה של מפתח reCAPTCHA קיים ל-iOS באחת מהדרכים הבאות:

    • כדי להעתיק את המזהה של מפתח קיים ממסוףGoogle Cloud :

      1. נכנסים לדף Google Cloud Fraud Defense.

        כניסה ל-Google Cloud Fraud Defense

      2. לוחצים על הכרטיסייה Keys.
      3. ברשימת מפתחות ה-reCAPTCHA, מוצאים את המפתח שרוצים להעתיק ולוחצים על .
    • כדי להעתיק את המזהה של מפתח קיים באמצעות API בארכיטקטורת REST, משתמשים ב-method‏ projects.keys.list.
    • כדי להעתיק את המזהה של מפתח קיים באמצעות ה-CLI של gcloud, משתמשים בפקודה gcloud recaptcha keys list.

  4. חשבון ב-GitHub.

  5. מידע על פרטיות של Apple

הכנת סביבת iOS

כדי להכין את סביבת הפיתוח:

  1. מורידים ומתקינים את הגרסה העדכנית של Xcode ויוצרים אפליקציה חדשה ריקה עם תצוגה אחת ל-iOS.

  2. מורידים את ה-SDK באחת מהדרכים הבאות:

    CocoaPods

    1. מורידים ומתקינים את CocoaPods.
    2. יוצרים Podfile ומוסיפים לו את השורות הבאות:

      source "https://github.com/CocoaPods/Specs.git"
      
      target 'AppTarget' do
      
        # Podfiles must include use_frameworks! or
        # use_frameworks! :linkage => :static
        use_frameworks!
      
        pod "RecaptchaEnterprise", "18.10.0-beta01"
        ...
      
      end
      
    3. מתקינים את יחסי התלות הנדרשים באמצעות הפקודה pod update.

    Swift Package Manager

    1. ב-Xcode, בוחרים באפשרות File > Add Packages (קובץ > הוספת חבילות) ומזינים את כתובת ה-URL הבאה בשדה Search (חיפוש) או Enter Package URL (הזנת כתובת URL של חבילה):

      https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk
      
    2. בתיבת הדו-שיח Xcode, מזינים את הפרטים הבאים:

      • שם המשתמש ב-GitHub.
      • טוקן גישה אישי שיצרתם לפי ההוראות של GitHub. טוקן הגישה האישי צריך לכלול את ההיקפים שמפורטים בתיבת הדו-שיח Xcode Sign In.

      ‫Xcode מתקין את ה-SDK ואת יחסי התלות הנדרשים שלו.

    Flutter

    הוראות מפורטות לשימוש ב-reCAPTCHA דרך Flutter זמינות במאמרי העזרה של Flutter.

    React Native

    הוראות מפורטות לשימוש ב-reCAPTCHA דרך React Native מופיעות במסמכי התיעוד של React Native.

    הורדה ישירה

    1. אם אתם רוצים להוריד את ה-SDK ואת יחסי התלות שלו כ-xcframeworks, הורידו את הלקוח.

שילוב של Fraud Defense באפליקציה ל-iOS

כדי לשלב את Fraud Defense באפליקציה ל-iOS, פועלים לפי השלבים הבאים ב-Xcode:

  1. כדי ליצור מופע של ה-SDK עם מפתח reCAPTCHA‏ (KEY_ID) שיצרתם, מעדכנים את האפליקציה באמצעות הקוד הבא:

    ‫Swift עם Storyboard

    1. עדכון של ViewController.swift.

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Task {
            do {
              self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
            } catch let error as RecaptchaError {
               print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
            }
          }
        }
      }
      

      אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
            guard let client = client else {
                print("RecaptchaClient creation error: \(error).")
              return
            }
            self.recaptchaClient = client
          }
        }
      }
      

    ‫Swift עם SwiftUI

    1. יוצרים כיתה ב-ViewModel.

      import RecaptchaEnterprise
      
      @MainActor class ViewModel: ObservableObject {
        private var recaptchaClient: RecaptchaClient?
      
        init() {
           Task {
            do {
              self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
            } catch let error as RecaptchaError {
               print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
            }
          }
        }
      }
      

      אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

      import RecaptchaEnterprise
      
      class ViewController: UIViewController {
        var recaptchaClient: RecaptchaClient?
      
        override func viewDidLoad() {
          super.viewDidLoad()
          Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
            guard let client = client else {
                print("RecaptchaClient creation error: \(error).")
              return
            }
            self.recaptchaClient = client
          }
        }
      }
      
    2. יוצרים מופע של ViewModel ב-ContentView.swift.

      import SwiftUI
      import RecaptchaEnterprise
      
      struct ContentView: View {
        @StateObject private var viewModel = ViewModel()
      
        var body: some View {
        }
      }
      
      struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
          ContentView()
        }
      }
      

    Objective-C

    1. אם האפליקציה שלכם כתובה ב-Objective-C, צרו קובץ Swift דמה וכללו את הייבוא הבא כדי לוודא ש-Xcode יכול למצוא את ספריות Swift ולקשר אליהן.

      import Foundation
      
    2. כדי לוודא שהקוד של Swift מקושר בצורה נכונה, עוברים אל Target > Build Settings > Always Embed Swift Standard Libraries ומוודאים שהאפשרות מוגדרת ל-Yes.

    3. עדכון של ViewController.h.

      #import <RecaptchaEnterprise/RecaptchaEnterprise.h>
      
      @interface ViewController : UIViewController
      @property (strong, atomic) RecaptchaClient *recaptchaClient;
      @end
      
    4. עדכון של ViewController.m.

      @implementation ViewController
      [Recaptcha fetchClientWithSiteKey:@"KEY_ID"
            completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
              if (!recaptchaClient) {
                NSLog(@"%@", (RecaptchaError *)error.errorMessage);
                return;
              }
              self->_recaptchaClient = recaptchaClient;
            }
      ];
      @end
      

    ההפעלה של ה-SDK יכולה להימשך כמה שניות. כדי לצמצם את זמן האחזור, צריך להפעיל את הלקוח מוקדם ככל האפשר, למשל במהלך הקריאה ל-onCreate() של מחלקת Application בהתאמה אישית. אל תגרמו לרכיבים בממשק המשתמש לחסום את ה-SDK של reCAPTCHA.

  2. יוצרים כפתור כדי להפעיל את reCAPTCHA ואת execute().

    ‫Swift עם Storyboard

    1. בסטוריבורד, יוצרים כפתור.
    2. יוצרים פעולה ב-ViewController שמקושרת לכפתור שיצרתם.
    3. מפעילים את ה-method‏ execute() ומעבירים פעולה מסוג Login כדי להחזיר אסימון reCAPTCHA באמצעות קטע הקוד הבא:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      Task {
        do {
          let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login)
          print(token)
        } catch let error as RecaptchaError {
          print(error.errorMessage)
        }
      }
      

      אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
      

    ‫Swift עם SwiftUI

    1. מעדכנים את ViewModel.swift באמצעות הקוד להרצה:

      import RecaptchaEnterprise
      
      @MainActor class ViewModel: ObservableObject {
      
        func execute() {
          guard let recaptchaClient = self.recaptchaClient else {
            print("Client not initialized correctly.")
            return
          }
      
          Task {
            do {
              let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login)
              print(token)
            } catch let error as RecaptchaError {
              print(error.errorMessage)
            }
          }
        }
      }
      

      אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

      guard let recaptchaClient = recaptchaClient else {
        print("RecaptchaClient creation failed.")
        return
      }
      recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
      
    2. מעדכנים את ContentView.swift.

      import SwiftUI
      import RecaptchaEnterprise
      
      struct ContentView: View {
        @StateObject private var viewModel = ViewModel()
      
        var body: some View {
      
          Button {
            viewModel.execute()
          } label: {
            Text("Execute")
          }.padding()
      
          Spacer()
        }
      }
      
      struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
          ContentView()
        }
      }
      

    Objective-C

    1. ב-storyboard, יוצרים כפתור.
    2. יוצרים פעולה ב-ViewController שמקושרת לכפתור שיצרתם.
    3. מפעילים את השיטה execute() ומעבירים פעולה מסוג Login כדי להחזיר טוקן של reCAPTCHA:

      if (!self->_recaptchaClient) {
        return;
      }
      
      [recaptchaClient execute:RecaptchaAction.login
          completion:^void(NSString* _Nullable  token, NSError* _Nullable error) {
        if (!token) {
          NSLog (@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        NSLog (@"%@", token);
      }];
      

    יכול להיות שיעברו כמה שניות עד שה-API‏ execute של הלקוח יסיים לפעול, למשל אם הרשת איטית או אם הוא ממתין להשלמת האתחול ברקע. חשוב לוודא שהקריאות ל-execute() לא חוסמות אירוע בממשק המשתמש, כמו לחיצה על כפתור.

  3. בודקים את האפליקציה:

    1. ‫reCAPTCHA משתמש ב-App Attest של אפל כחלק ממנוע הזיהוי שלו. אם אתם לא מתכננים להשתמש במפתח בדיקה עם ניקוד קבוע לפיתוח מקומי, בצעו את הפעולות הבאות:

      1. ב-Xcode, מוסיפים לאפליקציה את היכולת App Attest.

      2. בקובץ .entitlements של הפרויקט, מגדירים את סביבת App Attest ל-production.

    2. כדי לנקות את סביבת ה-build של Xcode, בתפריט Product לוחצים על Clean Build Folder.

    3. כדי להריץ את האפליקציה, בתפריט Product לוחצים על Run.

    4. באפליקציה שנטענה, לוחצים על הכפתור שיצרתם קודם.

    5. בחלון הפלט של ניפוי הבאגים, בודקים אם מופיע אסימון reCAPTCHA (מחרוזת אלפאנומרית). אם הוא מופיע, סימן שההטמעה הצליחה.

מעבר מהשיטה getClient לשיטה fetchClient

ה-method‏ fetchClient מחזירה RecaptchaClient שמנסה שוב לבצע אתחול במקרה של כשלים ברשת. אם לאפליקציה אין גישה לרשת כשהלקוח נוצר, הלקוח ממשיך לנסות שוב ומבצע אתחול בהצלחה כשהוא מתחבר לרשת.

אם קוראים ל-execute(timeout) והלקוח עדיין לא מוכן, הוא מנסה לבצע אתחול לפני שהוא מחזיר אסימון או RecaptchaError.

בדוגמה הבאה אפשר לראות איך עוברים מ-getClient ל-fetchClient.

‫Swift עם Storyboard

// Migrate from getClient
func initializeWithGetClient() {
  Task {
    do {
      self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

// Migrate to fetchClient
func initializeWithFetchClient() {
  Task {
    do {
      self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

// Migrate from getClient
override func initializeWithGetClient() {
  Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

// Migrate to fetchClient
override func initializeWithFetchClient() {
  Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

‫Swift עם SwiftUI

// Migrate from getClient
func initializeWithGetClient() {
    Task {
    do {
      self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

// Migrate to fetchClient
func initializeWithFetchClient() {
    Task {
    do {
      self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
    } catch let error as RecaptchaError {
        print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
    }
  }
}

אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

// Migrate from getClient
func initializeWithGetClient() {
  super.viewDidLoad()
  Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

// Migrate to fetchClient
func initializeWithFetchClient() {
  super.viewDidLoad()
  Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
    guard let client = client else {
        print("RecaptchaClient creation error: \(error).")
      return
    }
    self.recaptchaClient = client
  }
}

Objective-C

// Migrate from getClient
@implementation ViewController
[Recaptcha getClientWithSiteKey:@"KEY_ID"
      completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
        if (!recaptchaClient) {
          NSLog(@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        self->_recaptchaClient = recaptchaClient;
      }
];
@end

// Migrate to fetchClient
@implementation ViewController
[Recaptcha fetchClientWithSiteKey:@"KEY_ID"
      completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
        if (!recaptchaClient) {
          NSLog(@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        self->_recaptchaClient = recaptchaClient;
      }
];
@end

הגדרת זמן קצוב לתפוגה של קריאות ל-API

אפשר לציין ערך של זמן קצוב לתפוגה לממשקי ה-API של execute באמצעות המאפיין withTimeout.

Swift

  1. הגדרת זמן קצוב לתפוגה בזמן קריאה ל-execute.

      Task {
        do {
          let token = try await recaptchaClient.execute(
            withAction: RecaptchaAction.login,
            withTimeout: 10000)
          print(token)
        } catch let error as RecaptchaError {
          print(error.errorMessage)
        }
      }
    

    אם גרסת מערכת ההפעלה המינימלית של האפליקציה היא פחות מ-13, צריך להשתמש במקום זאת ב-trailing closure:

      recaptchaClient.execute(
        withAction: RecaptchaAction.login,
        withTimeout: 10000
      ) { token, error in
        if let token = token {
          print(token)
        } else {
          print(error)
        }
      }
    

Objective-C

  1. הגדרת זמן קצוב לתפוגה בזמן קריאה ל-execute.

      [recaptchaClient execute:RecaptchaAction.login
          withTimeout:10000.0
          completion:^void(NSString* _Nullable  token, NSError* _Nullable error) {
        if (!token) {
          NSLog (@"%@", (RecaptchaError *)error.errorMessage);
          return;
        }
        NSLog (@"%@", token);
      }];
    

טיפול בשגיאות

אם האפליקציה לא מצליחה לתקשר עם שירות reCAPTCHA, יכול להיות שה-API נתקל בשגיאה. אתם צריכים להוסיף לוגיקה באפליקציה כדי לטפל בשגיאות כאלה בצורה חלקה.

למידע נוסף על פתרונות לשגיאות נפוצות ב-API, ראו RecaptchaErrorCode.

מאמרי העזרה של ה-API

לעיון במאמר העזרה המלא של reCAPTCHA API ל-iOS, ראו RecaptchaEnterprise.

המאמרים הבאים

  • כדי להעריך את טוקן התגובה של reCAPTCHA, יוצרים הערכה.