Udostępnij za pośrednictwem


Samouczek: logowanie użytkowników w aplikacji mobilnej systemu iOS (Swift)

Dotyczy: Zielony okrąg z białym symbolem znacznika wyboru. Dzierżawcy siły roboczej Zielony okrąg z białym symbolem znacznika wyboru. Dzierżawcy zewnętrzni (dowiedz się więcej)

Jest to trzeci samouczek z serii samouczków, który przeprowadzi Cię przez proces logowania użytkowników przy użyciu identyfikatora Entra firmy Microsoft.

Przed rozpoczęciem użyj selektora Wybierz typ najemcy znajdującego się w górnej części tej strony, aby wybrać typ najemcy. Microsoft Entra ID oferuje dwie konfiguracje dzierżawy: pracowników i zewnętrzna. Konfiguracja dzierżawy zasobów pracowniczych obejmuje pracowników, aplikacje wewnętrzne i inne zasoby organizacyjne. Zewnętrzny dzierżawca jest przeznaczony dla aplikacji skierowanych do klientów.

W tym samouczku:

  • Zaloguj się użytkownik.
  • Wyloguj użytkownika.
  • Tworzenie interfejsu użytkownika aplikacji

Warunki wstępne

Logowanie użytkownika

Istnieją dwie główne opcje logowania użytkowników przy użyciu biblioteki Microsoft Authentication Library (MSAL) dla systemu iOS: uzyskiwanie tokenów interaktywnie lub dyskretnie.

  1. Aby interaktywnie zalogować się użytkownika, użyj następującego kodu:

    func acquireTokenInteractively() {
    
        guard let applicationContext = self.applicationContext else { return }
        guard let webViewParameters = self.webViewParameters else { return }
    
        // #1
        let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters)
        parameters.promptType = .selectAccount
    
        // #2
        applicationContext.acquireToken(with: parameters) { (result, error) in
    
            // #3
            if let error = error {
    
                self.updateLogging(text: "Could not acquire token: \(error)")
                return
            }
    
            guard let result = result else {
    
                self.updateLogging(text: "Could not acquire token: No result returned")
                return
            }
    
            // #4
            self.accessToken = result.accessToken
            self.updateLogging(text: "Access token is \(self.accessToken)")
            self.updateCurrentAccount(account: result.account)
            self.getContentWithToken()
        }
    }
    

    Właściwość promptType elementu MSALInteractiveTokenParameters konfiguruje zachowanie uwierzytelniania i monitu o wyrażenie zgody. Obsługiwane są następujące wartości:

    • .promptIfNecessary (wartość domyślna) — użytkownik jest monitowany tylko w razie potrzeby. Doświadczenie logowania jednokrotnego (SSO) jest określane przez obecność plików cookie w interfejsie przeglądarki oraz rodzaj konta. Jeśli wielu użytkowników jest zalogowanych, zostanie wyświetlony proces wyboru konta. Jest to zachowanie domyślne.
    • .selectAccount — jeśli żaden użytkownik nie zostanie określony, w widoku internetowym uwierzytelniania zostanie wyświetlona lista aktualnie zalogowanych kont dla użytkownika do wyboru.
    • .login — wymaga uwierzytelnienia użytkownika w widoku internetowym. Tylko jedno konto może być zalogowane naraz, jeśli określisz tę wartość.
    • .consent — wymaga od użytkownika wyrażenia zgody na bieżący zestaw zakresów żądania.
  2. Aby zalogować użytkownika w trybie dyskretnym, użyj następującego kodu:

    
        func acquireTokenSilently(_ account : MSALAccount!) {
    
            guard let applicationContext = self.applicationContext else { return }
    
            /**
    
             Acquire a token for an existing account silently
    
             - forScopes:           Permissions you want included in the access token received
             in the result in the completionBlock. Not all scopes are
             guaranteed to be included in the access token returned.
             - account:             An account object that we retrieved from the application object before that the
             authentication flow will be locked down to.
             - completionBlock:     The completion block that will be called when the authentication
             flow completes, or encounters an error.
             */
    
            let parameters = MSALSilentTokenParameters(scopes: kScopes, account: account)
    
            applicationContext.acquireTokenSilent(with: parameters) { (result, error) in
    
                if let error = error {
    
                    let nsError = error as NSError
    
                    // interactionRequired means we need to ask the user to sign-in. This usually happens
                    // when the user's Refresh Token is expired or if the user has changed their password
                    // among other possible reasons.
    
                    if (nsError.domain == MSALErrorDomain) {
    
                        if (nsError.code == MSALError.interactionRequired.rawValue) {
    
                            DispatchQueue.main.async {
                                self.acquireTokenInteractively()
                            }
                            return
                        }
                    }
    
                    self.updateLogging(text: "Could not acquire token silently: \(error)")
                    return
                }
    
                guard let result = result else {
    
                    self.updateLogging(text: "Could not acquire token: No result returned")
                    return
                }
    
                self.accessToken = result.accessToken
                self.updateLogging(text: "Refreshed Access token is \(self.accessToken)")
                self.updateSignOutButton(enabled: true)
                self.getContentWithToken()
            }
        }
    

    Metoda acquireTokenSilently próbuje w sposób dyskretny uzyskać token dostępu dla istniejącego konta MSAL. Używa applicationContext do żądania tokenu z określonymi zakresami. Jeśli wystąpi błąd, sprawdza, czy jest wymagana interakcja użytkownika, a jeśli tak, inicjuje pozyskiwanie tokenu interakcyjnego. Po powodzeniu aktualizuje token dostępu, rejestruje wynik, włącza przycisk wylogowywanie i pobiera zawartość przy użyciu tokenu.

Obsługa wywołania zwrotnego logowania (tylko system iOS)

Otwórz plik AppDelegate.swift . Aby obsłużyć wywołanie zwrotne po zalogowaniu, dodaj MSALPublicClientApplication.handleMSALResponse do klasy appDelegate w następujący sposób:

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

        return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String)
}

Jeśli używasz środowiska Xcode 11, należy umieścić wywołanie zwrotne biblioteki MSAL w pliku SceneDelegate.swift . Jeśli dla zgodności ze starszymi wersjami iOS obsługiwane są zarówno UISceneDelegate, jak i UIApplicationDelegate, wywołanie zwrotne MSAL musi zostać umieszczone w obu plikach.

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

        guard let urlContext = URLContexts.first else {
            return
        }

        let url = urlContext.url
        let sourceApp = urlContext.options.sourceApplication

        MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: sourceApp)
    }

Wyloguj użytkownika

Ważny

Wylogowywanie przy użyciu biblioteki MSAL usuwa wszystkie znane informacje o użytkowniku z aplikacji, a także usuwa aktywną sesję na urządzeniu, jeśli jest to dozwolone przez konfigurację urządzenia. Możesz również opcjonalnie wylogować użytkownika z przeglądarki.

Aby dodać możliwość wylogowywania, dodaj następujący kod w klasie ViewController.

@objc func signOut(_ sender: AnyObject) {

        guard let applicationContext = self.applicationContext else { return }

        guard let account = self.currentAccount else { return }

        do {

            /**
             Removes all tokens from the cache for this application for the provided account

             - account:    The account to remove from the cache
             */

            let signoutParameters = MSALSignoutParameters(webviewParameters: self.webViewParameters!)
            signoutParameters.signoutFromBrowser = false // set this to true if you also want to signout from browser or webview

            applicationContext.signout(with: account, signoutParameters: signoutParameters, completionBlock: {(success, error) in

                if let error = error {
                    self.updateLogging(text: "Couldn't sign out account with error: \(error)")
                    return
                }

                self.updateLogging(text: "Sign out completed successfully")
                self.accessToken = ""
                self.updateCurrentAccount(account: nil)
            })

        }
    }

Tworzenie interfejsu użytkownika aplikacji

Teraz utwórz interfejs użytkownika zawierający przycisk wywołujący interfejs API programu Microsoft Graph, inny do wylogowania i widok tekstowy, aby wyświetlić dane wyjściowe, dodając następujący kod do klasy ViewController:

Interfejs użytkownika systemu iOS

var loggingText: UITextView!
var signOutButton: UIButton!
var callGraphButton: UIButton!
var usernameLabel: UILabel!

func initUI() {

    usernameLabel = UILabel()
    usernameLabel.translatesAutoresizingMaskIntoConstraints = false
    usernameLabel.text = ""
    usernameLabel.textColor = .darkGray
    usernameLabel.textAlignment = .right

    self.view.addSubview(usernameLabel)

    usernameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true
    usernameLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10.0).isActive = true
    usernameLabel.widthAnchor.constraint(equalToConstant: 300.0).isActive = true
    usernameLabel.heightAnchor.constraint(equalToConstant: 50.0).isActive = true

    // Add call Graph button
    callGraphButton  = UIButton()
    callGraphButton.translatesAutoresizingMaskIntoConstraints = false
    callGraphButton.setTitle("Call Microsoft Graph API", for: .normal)
    callGraphButton.setTitleColor(.blue, for: .normal)
    callGraphButton.addTarget(self, action: #selector(callGraphAPI(_:)), for: .touchUpInside)
    self.view.addSubview(callGraphButton)

    callGraphButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    callGraphButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 120.0).isActive = true
    callGraphButton.widthAnchor.constraint(equalToConstant: 300.0).isActive = true
    callGraphButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true

    // Add sign out button
    signOutButton = UIButton()
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.setTitle("Sign Out", for: .normal)
    signOutButton.setTitleColor(.blue, for: .normal)
    signOutButton.setTitleColor(.gray, for: .disabled)
    signOutButton.addTarget(self, action: #selector(signOut(_:)), for: .touchUpInside)
    self.view.addSubview(signOutButton)

    signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    signOutButton.topAnchor.constraint(equalTo: callGraphButton.bottomAnchor, constant: 10.0).isActive = true
    signOutButton.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
    signOutButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true

    let deviceModeButton = UIButton()
    deviceModeButton.translatesAutoresizingMaskIntoConstraints = false
    deviceModeButton.setTitle("Get device info", for: .normal);
    deviceModeButton.setTitleColor(.blue, for: .normal);
    deviceModeButton.addTarget(self, action: #selector(getDeviceMode(_:)), for: .touchUpInside)
    self.view.addSubview(deviceModeButton)

    deviceModeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    deviceModeButton.topAnchor.constraint(equalTo: signOutButton.bottomAnchor, constant: 10.0).isActive = true
    deviceModeButton.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
    deviceModeButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true

    // Add logging textfield
    loggingText = UITextView()
    loggingText.isUserInteractionEnabled = false
    loggingText.translatesAutoresizingMaskIntoConstraints = false

    self.view.addSubview(loggingText)

    loggingText.topAnchor.constraint(equalTo: deviceModeButton.bottomAnchor, constant: 10.0).isActive = true
    loggingText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10.0).isActive = true
    loggingText.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true
    loggingText.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 10.0).isActive = true
}

func platformViewDidLoadSetup() {

    NotificationCenter.default.addObserver(self,
                        selector: #selector(appCameToForeGround(notification:)),
                        name: UIApplication.willEnterForegroundNotification,
                        object: nil)

}

@objc func appCameToForeGround(notification: Notification) {
    self.loadCurrentAccount()
}

Interfejs użytkownika systemu macOS


var callGraphButton: NSButton!
var loggingText: NSTextView!
var signOutButton: NSButton!

var usernameLabel: NSTextField!

func initUI() {

    usernameLabel = NSTextField()
    usernameLabel.translatesAutoresizingMaskIntoConstraints = false
    usernameLabel.stringValue = ""
    usernameLabel.isEditable = false
    usernameLabel.isBezeled = false
    self.view.addSubview(usernameLabel)

    usernameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 30.0).isActive = true
    usernameLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10.0).isActive = true

    // Add call Graph button
    callGraphButton  = NSButton()
    callGraphButton.translatesAutoresizingMaskIntoConstraints = false
    callGraphButton.title = "Call Microsoft Graph API"
    callGraphButton.target = self
    callGraphButton.action = #selector(callGraphAPI(_:))
    callGraphButton.bezelStyle = .rounded
    self.view.addSubview(callGraphButton)

    callGraphButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    callGraphButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true
    callGraphButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true

    // Add sign out button
    signOutButton = NSButton()
    signOutButton.translatesAutoresizingMaskIntoConstraints = false
    signOutButton.title = "Sign Out"
    signOutButton.target = self
    signOutButton.action = #selector(signOut(_:))
    signOutButton.bezelStyle = .texturedRounded
    self.view.addSubview(signOutButton)

    signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    signOutButton.topAnchor.constraint(equalTo: callGraphButton.bottomAnchor, constant: 10.0).isActive = true
    signOutButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true
    signOutButton.isEnabled = false

    // Add logging textfield
    loggingText = NSTextView()
    loggingText.translatesAutoresizingMaskIntoConstraints = false

    self.view.addSubview(loggingText)

    loggingText.topAnchor.constraint(equalTo: signOutButton.bottomAnchor, constant: 10.0).isActive = true
    loggingText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10.0).isActive = true
    loggingText.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true
    loggingText.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10.0).isActive = true
    loggingText.widthAnchor.constraint(equalToConstant: 500.0).isActive = true
    loggingText.heightAnchor.constraint(equalToConstant: 300.0).isActive = true
}

func platformViewDidLoadSetup() {}

Następnie w klasie ViewController zastąp metodę viewDidLoad():

    override func viewDidLoad() {

        super.viewDidLoad()

        initUI()

        do {
            try self.initMSAL()
        } catch let error {
            self.updateLogging(text: "Unable to create Application Context \(error)")
        }

        self.loadCurrentAccount()
        self.platformViewDidLoadSetup()
    }

Następne kroki

Jest to trzeci samouczek z serii samouczków, który przeprowadzi Cię przez proces logowania użytkowników przy użyciu identyfikatora Entra firmy Microsoft.

Przed rozpoczęciem użyj selektora Wybierz typ najemcy znajdującego się w górnej części tej strony, aby wybrać typ najemcy. Microsoft Entra ID oferuje dwie konfiguracje dzierżawy: pracowników i zewnętrzna. Konfiguracja dzierżawy zasobów pracowniczych obejmuje pracowników, aplikacje wewnętrzne i inne zasoby organizacyjne. Zewnętrzny dzierżawca jest przeznaczony dla aplikacji skierowanych do klientów.

W tym samouczku:

  • Zaloguj się użytkownik.
  • Wyloguj użytkownika.

Warunki wstępne

Logowanie użytkownika

Istnieją dwie główne opcje logowania użytkowników przy użyciu biblioteki Microsoft Authentication Library (MSAL) dla systemu iOS: uzyskiwanie tokenów interaktywnie lub dyskretnie.

  1. Aby interaktywnie zalogować się użytkownika, użyj następującego kodu:

    acquireTokenInteractively() {
        guard let applicationContext = self.applicationContext else { return }
        guard let webViewParameters = self.webViewParameters else { return }
    
        updateLogging(text: "Acquiring token interactively...")
    
        let parameters = MSALInteractiveTokenParameters(scopes: Configuration.kScopes, webviewParameters: webViewParameters)
        parameters.promptType = .selectAccount
    
        applicationContext.acquireToken(with: parameters) { (result, error) in
    
            if let error = error {
    
                self.updateLogging(text: "Could not acquire token: \(error)")
                return
            }
    
            guard let result = result else {
    
                self.updateLogging(text: "Could not acquire token: No result returned")
                return
            }
    
            self.accessToken = result.accessToken
            self.updateLogging(text: "Access token is \(self.accessToken)")
            self.updateCurrentAccount(account: result.account)
        }
    }
    

    Kod najpierw sprawdza, czy kontekst aplikacji i parametry widoku internetowego są dostępne. Następnie aktualizuje logowanie, aby wskazać, że token jest uzyskiwany interaktywnie. Następnie konfiguruje parametry pozyskiwania tokenu interakcyjnego, określając zakresy i parametry widoku internetowego. Ustawia również rodzaj monitu na wybór konta.

    Następnie wywołuje metodę acquireToken w kontekście aplikacji ze zdefiniowanymi parametrami. W funkcji obsługi zakończenia sprawdza się wszelkie błędy. Jeśli wystąpi błąd, zaktualizuje on rejestrowanie za pomocą komunikatu o błędzie. W przypadku powodzenia pobiera token dostępu z wyniku, aktualizuje rejestrowanie przy użyciu tokenu i aktualizuje bieżące konto.

    Gdy aplikacja uzyska token dostępu, możesz pobrać oświadczenia skojarzone z bieżącym kontem. W tym celu użyj następującego fragmentu kodu:

    let claims = result.account.accountClaims
    let preferredUsername = claims?["preferred_username"] as? String
    

    Kod odczytuje oświadczenia z konta, korzystając z właściwości accountClaims obiektu result.account. Następnie pobiera wartość oświadczenia "preferred_username" ze słownika oświadczeń i przypisuje ją do zmiennej preferredUsername.

  2. Aby zalogować użytkownika w trybie dyskretnym, użyj następującego kodu:

    func acquireTokenSilently() {
        self.loadCurrentAccount { (account) in
    
            guard let currentAccount = account else {
    
                self.updateLogging(text: "No token found, try to acquire a token interactively first")
                return
            }
    
            self.acquireTokenSilently(currentAccount)
        }
    }
    

    Kod inicjuje proces uzyskiwania tokenów w trybie dyskretnym. Najpierw próbuje załadować bieżące konto. Jeśli zostanie znalezione bieżące konto, przejdzie do uzyskania tokenu w trybie dyskretnym przy użyciu tego konta. Jeśli nie znaleziono bieżącego konta, system zaktualizuje logowanie, aby wskazać, że nie znaleziono tokenu, i sugeruje, aby spróbować zdobyć token w sposób interaktywny najpierw.

    W powyższym kodzie wywołujemy dwie funkcje, loadCurrentAccount i acquireTokenSilently. Funkcja loadCurrentAccount powinna mieć następujący kod:

    func loadCurrentAccount(completion: AccountCompletion? = nil) {
    
        guard let applicationContext = self.applicationContext else { return }
    
        let msalParameters = MSALParameters()
        msalParameters.completionBlockQueue = DispatchQueue.main
    
        // Note that this sample showcases an app that signs in a single account at a time
        applicationContext.getCurrentAccount(with: msalParameters, completionBlock: { (currentAccount, previousAccount, error) in
    
            if let error = error {
                self.updateLogging(text: "Couldn't query current account with error: \(error)")
                return
            }
    
            if let currentAccount = currentAccount {
    
                self.updateCurrentAccount(account: currentAccount)
                self.acquireTokenSilently(currentAccount)
    
                if let completion = completion {
                    completion(self.currentAccount)
                }
    
                return
            }
    
            // If testing with Microsoft's shared device mode, see the account that has been signed out from another app. More details here:
            // https://docs.microsoft.com/azure/active-directory/develop/msal-ios-shared-devices
            if let previousAccount = previousAccount {
    
                self.updateLogging(text: "The account with username \(String(describing: previousAccount.username)) has been signed out.")
    
            } else {
    
                self.updateLogging(text: "")
            }
    
            self.accessToken = ""
            self.updateCurrentAccount(account: nil)
    
            if let completion = completion {
                completion(nil)
            }
        })
    }
    

    Kod używa biblioteki MSAL dla systemu iOS do załadowania bieżącego konta. Sprawdza błędy i odpowiednio aktualizuje rejestrowanie. Jeśli zostanie znalezione bieżące konto, aktualizuje je i próbuje uzyskać tokeny w trybie dyskretnym. Jeśli istnieje poprzednie konto, rejestruje wylogowanie. Jeśli nie znaleziono żadnych kont, czyści token dostępu. Na koniec wykonuje blok ukończenia, jeśli zostanie podany.

    Funkcja acquireTokenSilently powinna zawierać następujący kod:

    func acquireTokenSilently(_ account : MSALAccount) {
        guard let applicationContext = self.applicationContext else { return }
    
        /**
    
         Acquire a token for an existing account silently
    
         - forScopes:           Permissions you want included in the access token received
         in the result in the completionBlock. Not all scopes are
         guaranteed to be included in the access token returned.
         - account:             An account object that we retrieved from the application object before that the
         authentication flow will be locked down to.
         - completionBlock:     The completion block that will be called when the authentication
         flow completes, or encounters an error.
         */
    
        updateLogging(text: "Acquiring token silently...")
    
        let parameters = MSALSilentTokenParameters(scopes: Configuration.kScopes, account: account)
    
        applicationContext.acquireTokenSilent(with: parameters) { (result, error) in
    
            if let error = error {
    
                let nsError = error as NSError
    
                // interactionRequired means we need to ask the user to sign-in. This usually happens
                // when the user's Refresh Token is expired or if the user has changed their password
                // among other possible reasons.
    
                if (nsError.domain == MSALErrorDomain) {
    
                    if (nsError.code == MSALError.interactionRequired.rawValue) {
    
                        DispatchQueue.main.async {
                            self.acquireTokenInteractively()
                        }
                        return
                    }
                }
    
                self.updateLogging(text: "Could not acquire token silently: \(error)")
                return
            }
    
            guard let result = result else {
    
                self.updateLogging(text: "Could not acquire token: No result returned")
                return
            }
    
            self.accessToken = result.accessToken
            self.updateLogging(text: "Refreshed Access token is \(self.accessToken)")
            self.updateSignOutButton(enabled: true)
        }
    }
    
    

    Ta funkcja używa biblioteki MSAL dla systemu iOS do dyskretnego uzyskiwania tokenu dla istniejącego konta. Po zweryfikowaniu applicationContextloguje proces pozyskiwania tokenu. Przy użyciu MSALSilentTokenParametersdefiniuje wymagane parametry. Następnie próbuje uzyskać token w trybie dyskretnym. Jeśli wystąpią błędy, sprawdza wymagania dotyczące interakcji z użytkownikiem, inicjując w razie potrzeby interaktywny proces. Po pomyślnym zakończeniu zaktualizuje właściwość accessToken i zapisze odświeżony token, kończąc przez włączenie przycisku wylogowania.

Wyloguj użytkownika

Aby wylogować użytkownika z aplikacji systemu iOS (Swift) przy użyciu biblioteki MSAL dla systemu iOS, użyj następującego kodu:

   @IBAction func signOut(_ sender: UIButton) {

        guard let applicationContext = self.applicationContext else { return }

        guard let account = self.currentAccount else { return }

        guard let webViewParameters = self.webViewParameters else { return }

        updateLogging(text: "Signing out...")

        do {

            /**
             Removes all tokens from the cache for this application for the provided account

             - account:    The account to remove from the cache
             */

            let signoutParameters = MSALSignoutParameters(webviewParameters: webViewParameters)

            // If testing with Microsoft's shared device mode, trigger signout from browser. More details here:
            // https://docs.microsoft.com/azure/active-directory/develop/msal-ios-shared-devices

            if (self.currentDeviceMode == .shared) {
                signoutParameters.signoutFromBrowser = true
            } else {
                signoutParameters.signoutFromBrowser = false
            }

            applicationContext.signout(with: account, signoutParameters: signoutParameters, completionBlock: {(success, error) in

                if let error = error {
                    self.updateLogging(text: "Couldn't sign out account with error: \(error)")
                    return
                }

                self.updateLogging(text: "Sign out completed successfully")
                self.accessToken = ""
                self.updateCurrentAccount(account: nil)
            })

        }
    }

Kod weryfikuje istnienie applicationContext, currentAccounti webViewParameters. Następnie rejestruje proces wylogowywania. Kod usuwa wszystkie tokeny z pamięci podręcznej dla podanego konta. W zależności od bieżącego trybu urządzenia określa, czy wylogować się z przeglądarki. Po zakończeniu aktualizuje odpowiednio tekst rejestrowania. Jeśli podczas procesu wylogowania wystąpi błąd, rejestruje komunikat o błędzie. Po pomyślnym wylogowaniu zmienia token dostępu na pusty ciąg znaków i usuwa dane bieżącego konta.

Następne kroki