Dodawanie logowania przez Google do aplikacji na iOS

1. Zanim zaczniesz

Z tego przewodnika dowiesz się, jak utworzyć aplikację na iOS, która implementuje logowanie przez Google i działa w symulatorze. Dostępne są implementacje korzystające zarówno z SwiftUI, jak i UIKit.

SwiftUI to nowoczesna platforma interfejsu użytkownika firmy Apple do tworzenia nowych aplikacji. Umożliwia tworzenie interfejsów użytkownika na wszystkich platformach Apple przy użyciu jednej wspólnej bazy kodu. Wymaga co najmniej systemu iOS 13.

UIKit to oryginalna i podstawowa platforma interfejsu użytkownika firmy Apple dla systemu iOS. Zapewnia zgodność wsteczną ze starszymi wersjami iOS. Dlatego jest to dobry wybór w przypadku aplikacji, które muszą obsługiwać różne starsze urządzenia.

Możesz wybrać ścieżkę, która najlepiej odpowiada Twoim potrzebom związanym z programowaniem.

Wymagania wstępne

Czego się nauczysz

  • Jak utworzyć projekt Google Cloud
  • Jak utworzyć klienty OAuth w konsoli Google Cloud
  • Jak wdrożyć funkcję Zaloguj się przez Google w aplikacji na iOS
  • Jak dostosować przycisk Zaloguj się przez Google
  • Jak zdekodować token identyfikatora
  • Jak włączyć Sprawdzanie aplikacji w przypadku aplikacji na iOS

Czego potrzebujesz

To ćwiczenie w Codelabs zostało utworzone przy użyciu Xcode 16.3 z symulatorem iOS 18.3. Do tworzenia aplikacji należy używać najnowszej wersji Xcode.

2. Tworzenie nowego projektu Xcode

  1. Otwórz Xcode i kliknij Create a new Xcode project (Utwórz nowy projekt w Xcode).
  2. Wybierz kartę iOS, kliknij szablon Aplikacja i kliknij Dalej.

Strona szablonu tworzenia projektu Xcode

  1. W opcjach projektu:
    • Wpisz nazwę produktu.
    • Opcjonalnie wybierz zespół.
    • Wpisz identyfikator organizacji.
    • Zanotuj wygenerowany identyfikator pakietu. Będą one potrzebne później.
    • W polu Interfejs wybierz jedną z tych opcji:
      • SwiftUI w przypadku aplikacji opartej na SwiftUI.
      • Scenorys aplikacji opartej na UIKit.
    • Wybierz Swift jako Język.
    • Kliknij Dalej i wybierz lokalizację, w której chcesz zapisać projekt.

Strona opcji projektu Xcode

3. Tworzenie klienta OAuth

Aby umożliwić aplikacji komunikację z usługami uwierzytelniania Google, musisz utworzyć identyfikator klienta OAuth. Wymaga to projektu Google Cloud. Poniżej znajdziesz instrukcje tworzenia projektu i identyfikatora klienta OAuth.

Wybieranie lub tworzenie projektu Google Cloud

  1. Otwórz konsolę Google Cloud i wybierz lub utwórz projekt. Jeśli wybierzesz istniejący projekt, konsola automatycznie przekieruje Cię do następnego wymaganego kroku.

Strona wyboru projektu w konsoli Google Cloud

  1. Wpisz nazwę nowego projektu Google Cloud.
  2. Kliknij Utwórz.

Strona wyboru projektu w konsoli Google Cloud

Jeśli ekran zgody został już skonfigurowany w wybranym projekcie, nie zobaczysz teraz prośby o jego skonfigurowanie. W takim przypadku możesz pominąć tę sekcję i przejść do tworzenia klienta OAuth 2.0.

  1. Kliknij Skonfiguruj ekran zgody.

Strona tworzenia klienta OAuth w konsoli Google Cloud z wymaganiem skonfigurowania ekranu zgody

  1. Na stronie promowania marki kliknij Rozpocznij.

Strona wprowadzająca do brandingu konsoli Google Cloud

  1. Na stronie konfiguracji projektu wypełnij te pola:
    • Informacje o aplikacji: wpisz nazwę aplikacji i adres e-mail dla użytkowników potrzebujących pomocy. Ten adres e-mail będzie publicznie wyświetlany, aby użytkownicy mogli kontaktować się z Tobą w sprawie pytań o ich zgodę.
    • Odbiorcy: kliknij Zewnętrzni.
    • Dane kontaktowe: wpisz adres e-mail, pod którym Google może się z Tobą skontaktować w sprawie projektu.
    • Zapoznaj się z zasadami dotyczącymi danych użytkownika w usługach interfejsów API Google.
    • Kliknij Utwórz.

Strona konfiguracji brandingu klienta w konsoli Google Cloud

  1. W menu nawigacyjnym kliknij stronę Klienci.
  2. Kliknij Utwórz klienta.

Strona klientów projektu Google Cloud

Tworzenie klienta OAuth 2.0

  1. Jako Typ aplikacji wybierz iOS.
  2. Wpisz nazwę klienta.
  3. Wpisz identyfikator pakietu utworzony w ostatnim kroku.
  4. Wpisz identyfikator zespołu przypisany do Twojego zespołu przez Apple. Ten krok jest na razie opcjonalny, ale identyfikator zespołu jest wymagany, aby włączyć weryfikację aplikacji w dalszej części tego laboratorium.
  5. Kliknij Utwórz.

Strona wprowadzania szczegółów klienta OAuth

  1. Skopiuj identyfikator klienta z okna dialogowego. Będzie on potrzebny później.
  2. Pobierz plik plist, aby móc z niego później korzystać.

Okno dialogowe z informacją o utworzeniu identyfikatora klienta OAuth

4. Konfigurowanie projektu Xcode

Następnym krokiem jest skonfigurowanie projektu Xcode do współpracy z pakietem SDK Logowanie przez Google. W tym celu musisz dodać pakiet SDK do projektu jako zależność i skonfigurować ustawienia projektu za pomocą unikalnego identyfikatora klienta. Ten identyfikator umożliwia pakietowi SDK bezpieczną komunikację z usługą uwierzytelniania Google podczas procesu logowania.

Instalowanie zależności funkcji Zaloguj się przez Google

  1. Otwórz projekt Xcode.
  2. Kliknij File > Add Package Dependencies (Plik > Dodaj zależności pakietu).
  3. Na pasku wyszukiwania wpisz adres URL repozytorium Logowanie przez Google: https://github.com/google/GoogleSignIn-iOS

Znajdź zależność Logowanie przez Google w menedżerze pakietów Swift

  1. Kliknij Dodaj pakiet.
  2. Wybierz główny cel aplikacji dla pakietu GoogleSignIn.
  3. Jeśli używasz SwiftUI, wybierz główny cel aplikacji dla pakietu GoogleSignInSwift. Jeśli planujesz używać UIKit, nie wybieraj celu dla tego pakietu.
  4. Kliknij Dodaj pakiet.

Dodawanie do projektu zależności Logowanie przez Google

Konfigurowanie danych logowania aplikacji

  1. W Nawigatorze projektu kliknij główny folder projektu.
  2. W głównym obszarze edytora wybierz główny cel aplikacji z listy CELE.
  3. U góry obszaru edytora kliknij kartę Informacje.
  4. Najedź kursorem na ostatni wiersz w sekcji Custom iOS Target Properties (Niestandardowe właściwości docelowe iOS) i kliknij wyświetlony przycisk +.

Dodawanie nowego klucza docelowego do usług docelowych na iOS

  1. W kolumnie Klucz wpisz GIDClientID.
  2. W kolumnie Wartość wklej identyfikator klienta skopiowany z konsoli Google Cloud.

Dodaj GIDClientID do głównego celu aplikacji

  1. Otwórz plik plist pobrany z konsoli Google Cloud.
  2. Skopiuj wartość pola Reversed Client ID (Odwrócony identyfikator klienta).

Plik plist w konsoli Google Cloud

  1. Rozwiń sekcję Typy adresów URL u dołu karty Informacje.
  2. Kliknij przycisk +.
  3. Wpisz odwrócony identyfikator klienta w polu Schematy adresów URL.

Dodawanie klucza URLSchemes do głównego celu aplikacji

Możemy teraz zacząć dodawać przycisk logowania do naszej aplikacji.

5. Dodawanie przycisku logowania

Po skonfigurowaniu projektu Xcode możesz zacząć dodawać do aplikacji przycisk Zaloguj się przez Google.

Główną logiką tego kroku jest wywołanie funkcji GIDSignIn.sharedInstance.signIn. Ta metoda rozpoczyna proces uwierzytelniania, przekazując kontrolę pakietowi SDK Logowanie przez Google, aby wyświetlić użytkownikowi proces logowania przez Google.

SwiftUI

  1. W Nawigatorze projektu Xcode znajdź plik ContentView.swift.
  2. Zastąp zawartość tego pliku tym tekstem:
import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack {
      GoogleSignInButton(action: handleSignInButton).padding()
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }
      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }
}

#Preview {
  ContentView()
}

Przycisk Zaloguj się przez Google w ramach SwiftUI w symulatorze iOS

UIKit

  1. W Xcode Project Navigator znajdź plik ViewController.swift.
  2. Zastąp zawartość tego pliku tym tekstem:
import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }
}

Przycisk Zaloguj się przez Google w ramach platformy UIKit w symulatorze iOS

Wyświetlanie przycisku logowania

Uruchom aplikację w symulatorze. Zobaczysz przycisk Zaloguj się przez Google, ale jeszcze nie będzie on działać prawidłowo. Jest to oczekiwane zachowanie, ponieważ musisz jeszcze zaimplementować kod, który będzie obsługiwać przekierowanie z powrotem do aplikacji po uwierzytelnieniu użytkownika.

6. Dostosowywanie przycisku logowania

Możesz dostosować domyślny przycisk Zaloguj się przez Google, aby lepiej pasował do motywu aplikacji. Pakiet SDK do logowania się przez Google umożliwia modyfikowanie schematu kolorów i stylu przycisku.

SwiftUI

Domyślny przycisk jest dodawany do strony za pomocą tego wiersza kodu:

GoogleSignInButton(action: handleSignInButton)

GoogleSignInButton jest dostosowywany przez przekazywanie parametrów do jego inicjatora. Poniższy kod spowoduje wyświetlenie przycisku logowania w trybie ciemnym.

  1. Otwórz ContentView.swift.
  2. Zaktualizuj inicjator zmiennej GoogleSignInButton, aby zawierał te wartości:
GoogleSignInButton(
  scheme: .dark,  // Options: .light, .dark, .auto
  style: .standard,  // Options: .standard, .wide, .icon
  state: .normal,  // Options: .normal, .disabled
  action: handleSignInButton
).padding()

Przycisk Zaloguj się przez Google w trybie ciemnym w platformie SwiftUI Framework na symulatorze iOS

Więcej informacji o opcjach dostosowywania znajdziesz w dokumentacji GoogleSignInSwift Framework Reference.

UIKit

Domyślny przycisk jest tworzony za pomocą tych wierszy kodu:

// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()

// Add the button to your view
view.addSubview(signInButton)

GIDSignInButton jest dostosowywany przez ustawienie właściwości w instancji przycisku. Poniższy kod spowoduje wyświetlenie przycisku logowania w trybie ciemnym.

  1. Otwórz plik ViewController.swift.
  2. Dodaj te wiersze kodu bezpośrednio przed dodaniem przycisku logowania do widoku w funkcji viewDidLoad:
// Set the width and color of the sign-in button
signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark  // Options: .dark, .light

Przycisk Zaloguj się przez Google w trybie ciemnym w ramach UIKit na symulatorze iOS

Więcej informacji o dostosowywaniu znajdziesz w dokumentacji GoogleSignIn Framework.

7. Obsługa adresu URL przekierowania uwierzytelniania

Po dodaniu przycisku logowania kolejnym krokiem jest obsługa przekierowania, które następuje po uwierzytelnieniu użytkownika. Po uwierzytelnieniu Google zwraca adres URL z tymczasowym kodem autoryzacji. Aby dokończyć proces logowania, moduł obsługi przechwytuje ten adres URL i przekazuje go do pakietu SDK Logowanie przez Google, aby wymienić go na podpisany token identyfikatora (JWT).

SwiftUI

  1. Otwórz plik zawierający strukturę App. Nazwa tego pliku jest tworzona na podstawie nazwy projektu, więc będzie to np. YourProjectNameApp.swift.
  2. Zastąp zawartość tego pliku tym tekstem:
import GoogleSignIn
import SwiftUI

@main
struct iOS_Sign_in_with_Google_App: App {
  var body: some Scene {
    WindowGroup {
      ContentView()

        .onOpenURL { url in
          GIDSignIn.sharedInstance.handle(url)
        }
    }
  }
}

UIKit

  1. Otwórz plik AppDelegate.swift.
  2. Dodaj na początku pliku ten import:
import GoogleSignIn
  1. Dodaj tę funkcję obsługi uwierzytelniania w klasie AppDelegate. Najlepiej umieścić go bezpośrednio po nawiasie klamrowym zamykającym metodę application(_:didFinishLaunchingWithOptions:):
func application(
  _ app: UIApplication,
  open url: URL,
  options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
  var handled: Bool

  handled = GIDSignIn.sharedInstance.handle(url)
  if handled {
    return true
  }
  // If not handled by this app, return false.
  return false
}

Po wprowadzeniu tych zmian plik AppDelegate.swift powinien wyglądać tak:

import GoogleSignIn
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // Override point for customization after application launch.
    return true
  }

  func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
    var handled: Bool

    handled = GIDSignIn.sharedInstance.handle(url)
    if handled {
      return true
    }
    // If not handled by this app, return false.
    return false
  }

  // MARK: UISceneSession Lifecycle

  func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(
      name: "Default Configuration",
      sessionRole: connectingSceneSession.role
    )
  }

  func application(
    _ application: UIApplication,
    didDiscardSceneSessions sceneSessions: Set<UISceneSession>
  ) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
  }
}

Testowanie procesu logowania

Możesz teraz przetestować cały proces logowania.

Uruchom aplikację i kliknij przycisk logowania. Po uwierzytelnieniu Google wyświetli ekran zgody, na którym możesz przyznać aplikacji uprawnienia dostępu do Twoich informacji. Gdy zatwierdzisz logowanie, zostanie ono sfinalizowane i wrócisz do aplikacji.

Po pomyślnym zakończeniu procesu logowania pakiet SDK Logowanie przez Google bezpiecznie przechowuje dane logowania użytkownika w pęku kluczy urządzenia. Te dane logowania mogą być później używane, aby użytkownik pozostawał zalogowany przy kolejnych uruchomieniach aplikacji.

8. Dodawanie przycisku wylogowania

Skoro logowanie działa, następnym krokiem jest dodanie przycisku wylogowania i zaktualizowanie interfejsu, aby odzwierciedlał bieżący stan logowania użytkownika. Gdy logowanie się powiedzie, pakiet SDK udostępnia obiekt GIDGoogleUser. Ten obiekt zawiera właściwość profile z podstawowymi informacjami, takimi jak imię i nazwisko oraz adres e-mail użytkownika, które możesz wykorzystać do personalizacji interfejsu.

SwiftUI

  1. Otwórz plik ContentView.swift.
  2. Dodaj zmienną stanu u góry struktury ContentView. Ta zmienna będzie zawierać informacje o użytkowniku po zalogowaniu się. Ponieważ jest to zmienna @State, SwiftUI automatycznie zaktualizuje interfejs, gdy tylko zmieni się jej wartość:
struct ContentView: View {
  @State private var user: GIDGoogleUser?
}
  1. Zastąp bieżącą wartość body w strukturze ContentView tą wartością VStack. Sprawdzi to, czy zmienna stanu user zawiera użytkownika. Jeśli tak, wyświetli wiadomość powitalną i przycisk wylogowania. W przeciwnym razie wyświetli oryginalny przycisk Zaloguj się przez Google:
var body: some View {
  VStack {
    // Check if the user is signed in.
    if let user = user {
      // If signed in, show a welcome message and the sign-out button.
      Text("Hello, \(user.profile?.givenName ?? "User")!")
        .font(.title)
        .padding()

      Button("Sign Out", action: signOut)
        .buttonStyle(.borderedProminent)

    } else {
      // If not signed in, show the "Sign in with Google" button.
      GoogleSignInButton(
        scheme: .dark,  // Options: .light, .dark, .auto
        style: .standard,  // Options: .standard, .wide, .icon
        state: .normal,  // Options: .normal, .disabled
        action: handleSignInButton
      ).padding()
    }
  }
}
  1. Zaktualizuj blok zakończenia handleSignInButton, aby przypisać signInResult.user do nowej zmiennej user. Oto co powoduje przełączenie interfejsu na widok po zalogowaniu:
func handleSignInButton() {
  // Find the current window scene.
  guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
    print("There is no active window scene")
    return
  }

  // Get the root view controller from the window scene.
  guard
    let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
      .rootViewController
  else {
    print("There is no key window or root view controller")
    return
  }

  // Start the sign-in process.
  GIDSignIn.sharedInstance.signIn(
    withPresenting: rootViewController
  ) { signInResult, error in
    guard let result = signInResult else {
      // Inspect error
      print("Error signing in: \(error?.localizedDescription ?? "No error description")")
      return
    }

    DispatchQueue.main.async {
      self.user = result.user
    }

    // If sign in succeeded, display the app's main content View.
    print("ID Token: \(result.user.idToken?.tokenString ?? "")")
  }
}
  1. Dodaj nową funkcję signOut na dole struktury ContentView, która będzie wywoływana przez przycisk wylogowania:
func signOut() {
  GIDSignIn.sharedInstance.signOut()
  // After signing out, set the `user` state variable to `nil`.
  self.user = nil
}

Uruchom aplikację i zaloguj się. Po udanym uwierzytelnieniu interfejs powinien się zmienić.

Stan zalogowania w ramach SwiftUI na symulatorze iOS

Po wprowadzeniu tych zmian plik ContentView.swift powinien wyglądać tak:

import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {

  @State private var user: GIDGoogleUser?

  var body: some View {
    VStack {
      // Check if the user is signed in.
      if let user = user {
        // If signed in, show a welcome message and the sign-out button.
        Text("Hello, \(user.profile?.givenName ?? "User")!")
          .font(.title)
          .padding()

        Button("Sign Out", action: signOut)
          .buttonStyle(.borderedProminent)

      } else {
        // If not signed in, show the "Sign in with Google" button.
        GoogleSignInButton(
          scheme: .dark,  // Options: .light, .dark, .auto
          style: .standard,  // Options: .standard, .wide, .icon
          state: .normal,  // Options: .normal, .disabled
          action: handleSignInButton
        ).padding()
      }
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      DispatchQueue.main.async {
        self.user = result.user
      }

      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }

  func signOut() {
    GIDSignIn.sharedInstance.signOut()
    // After signing out, set the `user` state variable to `nil`.
    self.user = nil
  }
}

#Preview {
  ContentView()
}

UIKit

  1. Otwórz plik ViewController.swift.
  2. U góry pliku ViewController, bezpośrednio pod deklaracją signInButton, dodaj przycisk wylogowania i etykietę powitalną:
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
  1. Dodaj tę funkcję na dole pliku ViewController. Ta funkcja wyświetli użytkownikowi inny interfejs w zależności od jego stanu logowania:
private func updateUI(for user: GIDGoogleUser?) {
  if let user = user {
    // User is signed in.
    signInButton.isHidden = true
    signOutButton.isHidden = false
    welcomeLabel.isHidden = false
    welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
  } else {
    // User is signed out.
    signInButton.isHidden = false
    signOutButton.isHidden = true
    welcomeLabel.isHidden = true
  }
}
  1. U dołu funkcji viewDidLoad dodaj ten kod, aby dodać do widoku etykietę powitalną i przycisk wylogowania:
// --- Set up the Welcome Label ---
welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
welcomeLabel.textAlignment = .center
welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
view.addSubview(welcomeLabel)

NSLayoutConstraint.activate([
  welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
])

// --- Set up the Sign-Out Button ---
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
view.addSubview(signOutButton)

NSLayoutConstraint.activate([
  signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
])

signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

// --- Set Initial UI State ---
updateUI(for: nil)
  1. Zmodyfikuj funkcję signInButtonTapped tak, aby po udanym logowaniu wywoływała metodę UpdateUI:
@objc func signInButtonTapped() {
  // Start the sign-in process.
  GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
    guard let result = signInResult else {
      // Inspect error
      print("Error signing in: \(error?.localizedDescription ?? "No error description")")
      return
    }

    // If sign in succeeded, print the ID token.
    print("ID Token: \(result.user.idToken?.tokenString ?? "")")

    DispatchQueue.main.async {
      self.updateUI(for: result.user)
    }
  }
}
  1. Na koniec dodaj funkcję signOutButtonTapped do ViewController, aby obsługiwać proces wylogowywania:
@objc func signOutButtonTapped() {
  GIDSignIn.sharedInstance.signOut()
  // Update the UI for the signed-out state.
  updateUI(for: nil)
}

Uruchom aplikację i zaloguj się. Po udanym uwierzytelnieniu interfejs powinien się zmienić.

Stan zalogowania w platformie UIKit w symulatorze iOS

Po wprowadzeniu tych zmian plik ViewController.swift powinien wyglądać tak:

import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()
  let signOutButton = UIButton(type: .system)
  let welcomeLabel = UILabel()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the width and color of the sign-in button
    signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
    signInButton.colorScheme = .dark  // Options: .dark, .light

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)

    // --- Set up the Welcome Label ---
    welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
    welcomeLabel.textAlignment = .center
    welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
    view.addSubview(welcomeLabel)

    NSLayoutConstraint.activate([
      welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
    ])

    // --- Set up the Sign-Out Button ---
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.setTitle("Sign Out", for: .normal)
    view.addSubview(signOutButton)

    NSLayoutConstraint.activate([
      signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
    ])

    signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

    // --- Set Initial UI State ---
    updateUI(for: nil)
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")

      DispatchQueue.main.async {
        self.updateUI(for: result.user)
      }
    }
  }

  private func updateUI(for user: GIDGoogleUser?) {
    if let user = user {
      // User is signed in.
      signInButton.isHidden = true
      signOutButton.isHidden = false
      welcomeLabel.isHidden = false
      welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
    } else {
      // User is signed out.
      signInButton.isHidden = false
      signOutButton.isHidden = true
      welcomeLabel.isHidden = true
    }
  }

  @objc func signOutButtonTapped() {
    GIDSignIn.sharedInstance.signOut()
    // Update the UI for the signed-out state.
    updateUI(for: nil)
  }
}

9. Przywracanie stanu logowania użytkownika

Aby zwiększyć komfort użytkowników, którzy wracają do aplikacji, następnym krokiem jest przywrócenie ich stanu logowania po uruchomieniu aplikacji. Wywołanie restorePreviousSignIn używa danych logowania zapisanych w pęku kluczy, aby automatycznie zalogować użytkownika z powrotem, dzięki czemu nie musi on za każdym razem przechodzić procesu logowania.

SwiftUI

  1. Otwórz plik ContentView.swift.
  2. Dodaj ten kod bezpośrednio po VStack w zmiennej body:
.onAppear {
  // On appear, try to restore a previous sign-in.
  GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
    // This closure is called when the restoration is complete.
    if let user = user {
      // If a user was restored, update the `user` state variable.
      DispatchQueue.main.async {
        self.user = user
      }

      // Print the ID token to the console when restored.
      print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
    }
  }
}

Plik ContentView.swift powinien wyglądać tak:

import GoogleSignIn
import GoogleSignInSwift
import SwiftUI

struct ContentView: View {

  @State private var user: GIDGoogleUser?

  var body: some View {
    VStack {
      // Check if the user is signed in.
      if let user = user {
        // If signed in, show a welcome message and the sign-out button.
        Text("Hello, \(user.profile?.givenName ?? "User")!")
          .font(.title)
          .padding()

        Button("Sign Out", action: signOut)
          .buttonStyle(.borderedProminent)

      } else {
        // If not signed in, show the "Sign in with Google" button.
        GoogleSignInButton(
          scheme: .dark,  // Options: .light, .dark, .auto
          style: .standard,  // Options: .standard, .wide, .icon
          state: .normal,  // Options: .normal, .disabled
          action: handleSignInButton
        ).padding()
      }
    }

    .onAppear {
      // On appear, try to restore a previous sign-in.
      GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
        // This closure is called when the restoration is complete.
        if let user = user {
          // If a user was restored, update the `user` state variable.
          DispatchQueue.main.async {
            self.user = user
          }

          // Print the ID token to the console when restored.
          print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
        }
      }
    }
  }

  func handleSignInButton() {
    // Find the current window scene.
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
      print("There is no active window scene")
      return
    }

    // Get the root view controller from the window scene.
    guard
      let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
        .rootViewController
    else {
      print("There is no key window or root view controller")
      return
    }

    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(
      withPresenting: rootViewController
    ) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      DispatchQueue.main.async {
        self.user = result.user
      }

      // If sign in succeeded, display the app's main content View.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")
    }
  }

  func signOut() {
    GIDSignIn.sharedInstance.signOut()
    // After signing out, set the `user` state variable to `nil`.
    self.user = nil
  }
}

#Preview {
  ContentView()
}

UIKit

  1. Otwórz plik ViewController.swift.
  2. Na końcu metody viewDidLoad dodaj to wywołanie restorePreviousSignIn:
// Attempt to restore a previous sign-in session
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
  if let user = user {
    print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")

    // Print the ID token when a session is restored.
    print("Restored ID Token: \(user.idToken?.tokenString ?? "")")

    // On success, update the UI for the signed-in state on the main thread.
    DispatchQueue.main.async {
      self.updateUI(for: user)
    }
  }
}

Plik ViewController.swift powinien wyglądać tak:

import GoogleSignIn
import UIKit

class ViewController: UIViewController {

  // Create an instance of the Sign in with Google button
  let signInButton = GIDSignInButton()
  let signOutButton = UIButton(type: .system)
  let welcomeLabel = UILabel()

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the width and color of the sign-in button
    signInButton.style = .standard  // Options: .standard, .wide, .iconOnly
    signInButton.colorScheme = .dark  // Options: .dark, .light

    // Add the sign-in button to your view
    view.addSubview(signInButton)

    // Position the button using constraints
    signInButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    ])

    // Add a target to the button to call a method when it's pressed
    signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)

    // --- Set up the Welcome Label ---
    welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
    welcomeLabel.textAlignment = .center
    welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
    view.addSubview(welcomeLabel)

    NSLayoutConstraint.activate([
      welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
    ])

    // --- Set up the Sign-Out Button ---
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.setTitle("Sign Out", for: .normal)
    view.addSubview(signOutButton)

    NSLayoutConstraint.activate([
      signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
      signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
    ])

    signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)

    // --- Set Initial UI State ---
    updateUI(for: nil)

    // Attempt to restore a previous sign-in session
    GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
      if let user = user {
        print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")

        // Print the ID token when a session is restored.
        print("Restored ID Token: \(user.idToken?.tokenString ?? "")")

        // On success, update the UI for the signed-in state on the main thread.
        DispatchQueue.main.async {
          self.updateUI(for: user)
        }
      }
    }
  }

  // This method is called when the sign-in button is pressed.
  @objc func signInButtonTapped() {
    // Start the sign-in process.
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
      guard let result = signInResult else {
        // Inspect error
        print("Error signing in: \(error?.localizedDescription ?? "No error description")")
        return
      }

      // If sign in succeeded, print the ID token.
      print("ID Token: \(result.user.idToken?.tokenString ?? "")")

      DispatchQueue.main.async {
        self.updateUI(for: result.user)
      }
    }
  }

  private func updateUI(for user: GIDGoogleUser?) {
    if let user = user {
      // User is signed in.
      signInButton.isHidden = true
      signOutButton.isHidden = false
      welcomeLabel.isHidden = false
      welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
    } else {
      // User is signed out.
      signInButton.isHidden = false
      signOutButton.isHidden = true
      welcomeLabel.isHidden = true
    }
  }

  @objc func signOutButtonTapped() {
    GIDSignIn.sharedInstance.signOut()
    // Update the UI for the signed-out state.
    updateUI(for: nil)
  }
}

Testowanie cichego logowania

Po zalogowaniu się zamknij aplikację i uruchom ją ponownie. Powinno nastąpić automatyczne zalogowanie bez konieczności klikania przycisku.

10. Informacje o tokenie identyfikatora

Obiekt GIDGoogleUser jest przydatny do personalizowania interfejsu za pomocą imienia i nazwiska oraz adresu e-mail użytkownika, ale najważniejszym elementem danych zwracanym przez pakiet SDK jest token identyfikatora.

W tych ćwiczeniach do sprawdzenia zawartości tokena JWT użyjemy narzędzia online. W aplikacji produkcyjnej należy wysłać ten token identyfikatora na serwer backendu. Serwer musi zweryfikować integralność tokena identyfikatora i użyć tokena JWT do bardziej złożonych działań, takich jak utworzenie nowego konta na platformie backendowej lub utworzenie nowej sesji użytkownika.

Dostęp do tokena JWT i jego dekodowanie

  1. Uruchom aplikację.
  2. Otwórz konsolę Xcode. Powinien pojawić się wydrukowany token identyfikatora. Będzie wyglądać mniej więcej tak: eyJhbGciOiJSUzI1Ni ... Hecz6Wm4Q.
  3. Skopiuj token identyfikatora i użyj narzędzia online, takiego jak jwt.io, aby zdekodować token JWT.

Zdekodowany token JWT będzie wyglądał tak:

{
  "alg": "RS256",
  "kid": "c8ab71530972bba20b49f78a09c9852c43ff9118",
  "typ": "JWT"
}
{
  "iss": "https://accounts.google.com",
  "azp": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
  "aud": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "email": "example@example.com",
  "email_verified": true,
  "at_hash": "JyCYDmHtzhjkb0-qJhKsMg",
  "name": "Kimya",
  "picture": "https://lh3.googleusercontent.com/a/ACg8ocIyy4VoR31t_n0biPVcScBHwZOCRaKVDb_MoaMYep65fyqoAw=s96-c",
  "given_name": "Kimya",
  "iat": 1758645896,
  "exp": 1758649496
}

Ważne pola tokena

Zdekodowany token identyfikatora zawiera pola o różnym przeznaczeniu. Niektóre z nich są łatwe do zrozumienia, np. imię i nazwisko czy adres e-mail, a inne są używane przez serwer backendu do weryfikacji.

Szczególnie ważne jest zrozumienie tego pola:

  • sub: pole sub to unikalny, stały identyfikator konta Google użytkownika. Użytkownik może zmienić swój podstawowy adres e-mail lub imię, ale jego identyfikator sub nigdy się nie zmieni. Dzięki temu pole sub jest idealną wartością do użycia jako klucz podstawowy kont użytkowników na backendzie.

Więcej informacji o znaczeniu wszystkich pól tokena znajdziesz w artykule Uzyskiwanie informacji o użytkowniku z tokena identyfikatora.

11. Zabezpieczanie aplikacji za pomocą usługi App Check

Zdecydowanie zalecamy włączenie weryfikacji aplikacji, aby mieć pewność, że tylko Twoja aplikacja może uzyskiwać dostęp do punktów końcowych protokołu OAuth 2.0 Google w imieniu Twojego projektu. Sprawdzanie aplikacji weryfikuje, czy żądania wysyłane do usług backendu pochodzą z autentycznej aplikacji na prawdziwym i niezmodyfikowanym urządzeniu.

Z tej sekcji dowiesz się, jak zintegrować weryfikację aplikacji z aplikacją i skonfigurować ją do debugowania w symulatorze oraz do wersji produkcyjnej działającej na prawdziwym urządzeniu.

Konfiguracja konsoli

Integracja usługi App Check z aplikacją wymaga jednorazowej konfiguracji w konsolach Google Cloud i Firebase. Obejmuje to włączenie weryfikacji aplikacji dla klienta OAuth iOS w konsoli Google Cloud, utworzenie klucza interfejsu API do użycia z dostawcą debugowania weryfikacji aplikacji oraz połączenie projektu Google Cloud z Firebase.

Włączanie usługi App Check w konsoli Google Cloud

  1. Otwórz listę klientów powiązanych z Twoim projektem Google Cloud.
  2. Wybierz identyfikator klienta OAuth 2.0 utworzony dla aplikacji na iOS.
  3. Włącz Sprawdzanie aplikacji w sekcji Tożsamość Google w systemie iOS.

Strona edycji klienta OAuth z przełącznikiem Sprawdzania aplikacji

  1. Kliknij Zapisz.

Tworzenie klucza interfejsu API

  1. Otwórz stronę Biblioteka interfejsów API w projekcie Google Cloud.
  2. Na pasku wyszukiwania wpisz Firebase App Check API.

Strona biblioteki interfejsów API w konsoli Google Cloud

  1. Wybierz i włącz interfejs Firebase App Check API.
  2. Otwórz Interfejsy API i usługi i w menu nawigacyjnym wybierz Dane logowania.
  3. U góry strony kliknij Utwórz dane logowania.

Strona danych logowania interfejsu API konsoli Google Cloud

  1. Przypisz nazwę do tego klucza interfejsu API.
  2. W sekcji Ograniczenia aplikacji wybierz Aplikacje na iOS.
  3. Dodaj identyfikator pakietu aplikacji jako zatwierdzoną aplikację.
  4. W sekcji Ograniczenia interfejsów API kliknij Ogranicz klucz.
  5. W menu wybierz Firebase App Check API.
  6. Kliknij Utwórz.

Strona tworzenia klucza interfejsu API konsoli Google Cloud

  1. Skopiuj utworzony klucz interfejsu API. Będzie on potrzebny w późniejszym kroku.

Dodawanie Firebase do projektu Google Cloud

  1. Otwórz konsolę Firebase.
  2. Kliknij Rozpocznij od skonfigurowania projektu Firebase.
  3. Wybierz Add Firebase to Google Cloud project (Dodaj Firebase do projektu Google Cloud).

Dodawanie Firebase do istniejącego projektu Google Cloud

  1. Wybierz projekt Google Cloud z menu i przejdź przez proces rejestracji.
  2. Kliknij Dodaj Firebase.
  3. Gdy projekt Firebase będzie gotowy, kliknij Dalej, aby go otworzyć.

Integracja kodu po stronie klienta

Po skonfigurowaniu projektu Google Cloud na potrzeby weryfikacji aplikacji możesz napisać kod po stronie klienta, aby ją włączyć. Dostawca używany do atestowania różni się w środowiskach produkcyjnym i debugowania. Aplikacja produkcyjna na prawdziwym urządzeniu korzysta z wbudowanej usługi App Attest firmy Apple, aby potwierdzić swoją autentyczność. Symulator iOS nie może jednak zapewnić tego rodzaju potwierdzenia, dlatego środowisko debugowania wymaga specjalnego dostawcy debugowania, któremu przekazywany jest klucz interfejsu API.

Poniższy kod obsługuje oba scenariusze, używając dyrektywy kompilatora do automatycznego wybierania odpowiedniego dostawcy w czasie kompilacji.

SwiftUI

  1. Otwórz główny plik aplikacji.
  2. Zdefiniuj tę klasę AppDelegate po zaimportowaniu i przed atrybutem @main:
class AppDelegate: NSObject, UIApplicationDelegate {
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        } else {
          print("GIDSignIn configured for App Check.")
        }
      }
    #endif

    return true
  }
}
  1. Zastąp "YOUR_API_KEY" w podanym kodzie kluczem interfejsu API skopiowanym z Google Cloud Console.
  2. Dodaj ten wiersz w strukturze App, tuż przed zmienną body. Rejestruje to klasę AppDelegate w cyklu życia aplikacji, co pozwala jej reagować na uruchomienie aplikacji i inne zdarzenia systemowe:
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

Główny plik aplikacji powinien wyglądać tak:

import GoogleSignIn
import SwiftUI

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        } else {
          print("GIDSignIn configured for App Check.")
        }
      }
    #endif

    return true
  }
}

@main
struct iOS_Sign_in_with_Google_App: App {

  @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

  var body: some Scene {
    WindowGroup {
      ContentView()

        .onOpenURL { url in
          GIDSignIn.sharedInstance.handle(url)
        }
    }
  }
}

UIKit

  1. Otwórz plik AppDelegate.swift.
  2. Zaktualizuj metodę application(_:didFinishLaunchingWithOptions:), aby zawierała inicjację Sprawdzania aplikacji:
func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

  #if targetEnvironment(simulator)
    // Configure for debugging on a simulator.
    // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
    let apiKey = "YOUR_API_KEY"
    GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
      if let error {
        print("Error configuring GIDSignIn debug provider: \(error)")
      }
    }
  #else
    // Configure GIDSignIn for App Check on a real device.
    GIDSignIn.sharedInstance.configure { error in
      if let error {
        print("Error configuring GIDSignIn for App Check: \(error)")
      }
    }
  #endif

  return true
}
  1. Zastąp "YOUR_API_KEY" w podanym kodzie kluczem interfejsu API skopiowanym z Google Cloud Console.

Plik AppDelegate.swift powinien wyglądać tak:

import GoogleSignIn
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    #if targetEnvironment(simulator)
      // Configure for debugging on a simulator.
      // TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
      let apiKey = "YOUR_API_KEY"
      GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
        if let error {
          print("Error configuring GIDSignIn debug provider: \(error)")
        }
      }
    #else
      // Configure GIDSignIn for App Check on a real device.
      GIDSignIn.sharedInstance.configure { error in
        if let error {
          print("Error configuring GIDSignIn for App Check: \(error)")
        }
      }
    #endif

    return true
  }

  func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
    var handled: Bool

    handled = GIDSignIn.sharedInstance.handle(url)
    if handled {
      return true
    }
    // If not handled by this app, return false.
    return false
  }

  // MARK: UISceneSession Lifecycle

  func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(
      name: "Default Configuration",
      sessionRole: connectingSceneSession.role
    )
  }

  func application(
    _ application: UIApplication,
    didDiscardSceneSessions sceneSessions: Set<UISceneSession>
  ) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
  }
}

Testowanie sprawdzania aplikacji w symulatorze

  1. Na pasku menu Xcode kliknij Product (Produkt) > Scheme (Schemat) > Edit Scheme (Edytuj schemat).
  2. W menu nawigacyjnym kliknij Uruchom.
  3. Kliknij kartę Arguments (Argumenty).
  4. W sekcji Arguments Passed on Launch (Argumenty przekazywane przy uruchamianiu) kliknij + i dodaj -FIRDebugEnabled. Ten argument uruchamiania włącza logowanie debugowania Firebase.
  5. Wybierz Zamknij.

Strona edytora argumentów Xcode

  1. Uruchom aplikację w symulatorze.
  2. Skopiuj token debugowania App Check, który jest wyświetlany w konsoli Xcode.

Token debugowania App Check w konsoli Xcode

  1. Otwórz projekt w konsoli Firebase.
  2. W menu nawigacyjnym rozwiń sekcję Tworzenie.
  3. Wybierz App Check.
  4. Kliknij kartę Aplikacje.
  5. Najedź kursorem na aplikację i kliknij ikonę menu z 3 kropkami.

Ustawienia Sprawdzania aplikacji Firebase

  1. Kliknij Zarządzaj tokenami debugowania.
  2. Kliknij Dodaj token debugowania.
  3. Nadaj tokenowi debugowania nazwę i wklej skopiowany wcześniej token debugowania jako wartość.
  4. Aby zarejestrować token, kliknij Zapisz.

Zarządzanie tokenami debugowania Sprawdzania aplikacji Firebase

  1. Wróć do symulatora i zaloguj się.

Zanim wskaźniki pojawią się w konsoli, może minąć kilka minut. Gdy to zrobią, możesz sprawdzić, czy usługa App Check działa, szukając wzrostu liczby żądań zweryfikowanych w jednym z tych miejsc:

  • W sekcji Weryfikacja aplikacji w konsoli Firebase na karcie Interfejsy API.

Dane Sprawdzania aplikacji Firebase

  • Na stronie edycji klienta OAuth w konsoli Google Cloud.

Dane w Google Cloud Console dotyczące weryfikacji aplikacji

Po monitorowaniu danych Sprawdzania aplikacji i potwierdzeniu, że uprawnione żądania są weryfikowane, włącz wymuszanie Sprawdzania aplikacji. Po włączeniu wymuszania Sprawdzanie aplikacji odrzuca wszystkie niezweryfikowane żądania, dzięki czemu tylko ruch z Twojej autentycznej aplikacji może uzyskiwać dostęp do punktów końcowych OAuth 2.0 Google w imieniu Twojego projektu.

12. Dodatkowe materiały

Gratulacje!

Skonfigurowano klienta OAuth 2.0 na iOS, dodano do aplikacji na iOS przycisk logowania przez Google, dostosowano wygląd przycisku, zdekodowano token identyfikatora JWT i włączono weryfikację aplikacji.

Te linki mogą Ci pomóc w wykonaniu kolejnych kroków:

Najczęstsze pytania