Aracılığıyla paylaş


iOS (Swift) mobil uygulamada kullanıcı oturum açma eğitimi

Şunlar için geçerlidir: Beyaz onay işareti simgesi olan yeşil daire. İş gücü kiracılarıBeyaz onay işareti simgesi olan yeşil daire.Dış kiracılar (daha fazla bilgi edinin)

Bu, Microsoft Entra Id kullanarak kullanıcılarda oturum açma konusunda size yol gösteren öğretici serisinin üçüncü öğreticisidir.

Başlamadan önce, kiracı türünü seçmek için bu sayfanın üst kısmındaki Kiracı türü seçici'i kullanın. Microsoft Entra ID, iş gücü ve dışolmak üzere iki kiracı yapılandırması sağlar. İş gücü kiracı yapılandırması çalışanlarınıza, iç uygulamalarınıza ve diğer kuruluş kaynaklarınıza yöneliktir. Dış kiracı, müşteriye yönelik uygulamalarınız içindir.

Bu öğreticide:

  • Kullanıcı oturum aç.
  • Kullanıcı oturumunu kapatın.
  • Uygulamanızın kullanıcı arabirimini oluşturma

Önkoşullar

Kullanıcı oturum aç

iOS için Microsoft Kimlik Doğrulama Kitaplığı'nı (MSAL) kullanarak kullanıcıların oturum açması için iki ana seçeneğiniz vardır: belirteçleri etkileşimli olarak veya sessizce almak.

  1. Kullanıcı etkileşimli olarak oturum açmak için aşağıdaki kodu kullanın:

    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()
        }
    }
    

    promptType MSALInteractiveTokenParameters özelliği, kimlik doğrulaması ve onay istemi davranışını yapılandırmaktadır. Aşağıdaki değerler desteklenir:

    • .promptIfNecessary (varsayılan ayar) - Kullanıcıdan yalnızca gerekirse istenir. SSO deneyimi, webview'de çerezlerin bulunmasına ve hesap türüne göre belirlenir. Birden çok kullanıcı oturum açtıysa hesap seçimi deneyimi sunulur. Bu,varsayılan davranıştır.
    • .selectAccount - Kullanıcı belirtilmezse, kimlik doğrulama web görünümü kullanıcının seçebilmek için şu anda oturum açmış olan hesapların listesini sunar.
    • .login - Kullanıcının web görünümünde kimlik doğrulamasını gerektirir. Bu değeri belirtirseniz aynı anda yalnızca bir hesap oturum açabilir.
    • .consent - Kullanıcının istek için geçerli kapsam kümesini onaylamasını gerektirir.
  2. Kullanıcının sessizce oturum açması için aşağıdaki kodu kullanın:

    
        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()
            }
        }
    

    acquireTokenSilently yöntemi, mevcut bir MSAL hesabı için sessizce erişim belirteci almayı dener. Belirtilen kapsamlara sahip belirteci istemek için applicationContext kullanır. Bir hata oluşursa, kullanıcı etkileşiminin gerekli olup olmadığını denetler ve gerekliyse etkileşimli bir belirteç alımı başlatır. Başarılı olduğunda erişim belirtecini günceller, sonucu günlüğe kaydeder, oturum kapatma düğmesini etkinleştirir ve belirteci kullanarak içeriği alır.

Oturum açma geri çağırmasını işleme (yalnızca iOS)

AppDelegate.swift dosyasını açın. Oturum açmadan sonra geri çağırmayı işlemek için MSALPublicClientApplication.handleMSALResponse sınıfına aşağıdaki gibi appDelegate ekleyin:

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

Xcode 11kullanıyorsanız bunun yerine SceneDelegate.swift MSAL geri çağırması yerleştirmelisiniz. Eski iOS ile uyumluluk için hem UISceneDelegate hem de UIApplicationDelegate'i destekliyorsanız, MSAL geri çağırmanın her iki dosyaya da yerleştirilmesi gerekir.

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

Oturumu kapatan kullanıcı

Önemli

MSAL ile oturum kapatıldığında kullanıcıyla ilgili tüm bilinen bilgiler uygulamadan kaldırılır ve cihaz yapılandırmasına izin verildiğinde cihazdaki etkin kullanıcı oturumu da sonlandırılır. İsterseniz kullanıcının tarayıcıdan oturumunu kapatabilirsiniz.

Oturum kapatma özelliği eklemek için aşağıdaki kodu ViewController sınıfına ekleyin.

@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)
            })

        }
    }

Uygulamanızın kullanıcı arabirimini oluşturma

Şimdi ViewController sınıfına aşağıdaki kodu ekleyerek Microsoft Graph API'sini çağırmak için bir düğme, oturumu kapatmak için başka bir düğme ve bazı çıktıları görmek için bir metin görünümü içeren bir kullanıcı arabirimi oluşturun:

iOS kullanıcı arabirimi

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()
}

macOS kullanıcı arabirimi


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() {}

Ardından, ViewController sınıfının içinde de viewDidLoad() yöntemini şununla değiştirin:

    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()
    }

Sonraki adımlar

Bu, Microsoft Entra Id kullanarak kullanıcılarda oturum açma konusunda size yol gösteren öğretici serisinin üçüncü öğreticisidir.

Başlamadan önce, kiracı türünü seçmek için bu sayfanın üst kısmındaki Kiracı türü seçici'i kullanın. Microsoft Entra ID, iş gücü ve dışolmak üzere iki kiracı yapılandırması sağlar. İş gücü kiracı yapılandırması çalışanlarınıza, iç uygulamalarınıza ve diğer kuruluş kaynaklarınıza yöneliktir. Dış kiracı, müşteriye yönelik uygulamalarınız içindir.

Bu öğreticide:

  • Kullanıcı oturum aç.
  • Kullanıcı oturumunu kapatın.

Önkoşullar

Kullanıcı oturum aç

iOS için Microsoft Kimlik Doğrulama Kitaplığı'nı (MSAL) kullanarak kullanıcıların oturum açması için iki ana seçeneğiniz vardır: belirteçleri etkileşimli olarak veya sessizce almak.

  1. Kullanıcı etkileşimli olarak oturum açmak için aşağıdaki kodu kullanın:

    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 önce uygulama bağlamı ve web görünümü parametrelerinin kullanılabilir olup olmadığını denetler. Ardından, belirtecin etkileşimli olarak edinildiğini göstermek için günlüğü günceller. Ardından, kapsamları ve web görünümü parametrelerini belirterek etkileşimli belirteç alımı için parametreler ayarlar. Ayrıca, bir hesap seçmek için istem türünü ayarlar.

    Daha sonra, tanımlanan parametrelerle uygulama bağlamında acquireToken yöntemini çağırır. Tamamlama işleyicisinde hataları denetler. Bir hata ile karşılaşıldığında, hata mesajını günlüğe kaydeder. Başarılı olursa, sonuçtan erişim belirtecini alır, kayıtlarını belirteçle günceller ve geçerli hesabı günceller.

    Uygulamanız bir erişim belirteci aldıktan sonra geçerli hesapla ilişkili talepleri alabilirsiniz. Bunu yapmak için aşağıdaki kod parçacığını kullanın:

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

    Kod, accountClaims nesnesinin result.account özelliğine erişerek hesaptan talepleri okur. Daha sonra talep sözlüğünden "preferred_username" talebi değerini alır ve preferredUsername değişkenine atar.

  2. Kullanıcının sessizce oturum açması için aşağıdaki kodu kullanın:

    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, belirteçleri sessizce alma işlemini başlatır. Geçerli hesabı yüklemeyi önce dener. Geçerli bir hesap bulunursa, bu hesabı kullanarak jetonu sessizce elde etmeye devam eder. Geçerli bir hesap bulunamazsa, belirteç bulunamadığını belirtmek için günlük kaydını günceller ve önce etkileşimli olarak bir belirteç edinmeyi denemeyi önerir.

    Yukarıdaki kodda loadCurrentAccount ve acquireTokenSilentlyiki işlevi çağırıyoruz. loadCurrentAccount işlevi aşağıdaki koda sahip olmalıdır:

    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, iOS'ta geçerli hesabı yüklemek için MSAL kullanır. Hataları kontrol eder ve günlüğü buna göre günceller. Geçerli bir hesap bulunursa, onu günceller ve belirteçleri sessizce almaya çalışır. Önceki bir hesap varsa oturum kapatmayı günlüğe kaydeder. Hesap bulunamazsa erişim belirtecini temizler. Son olarak, eğer bir tamamlama bloğu sağlanmışsa, onu gerçekleştirir.

    acquireTokenSilently işlevi aşağıdaki kodu içermelidir:

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

    Bu işlev, mevcut bir hesap için gizlice bir belirteç elde etmek amacıyla iOS için MSAL kullanır. applicationContext doğrulandıktan sonra, belirteç alma süreci günlük kaydına işlenir. MSALSilentTokenParameterskullanarak gerekli parametreleri tanımlar. Ardından belirteci sessizce almayı dener. Hatalar varsa kullanıcı etkileşimi gereksinimlerini denetler ve gerekirse etkileşimli bir işlem başlatır. Başarılı olduğunda, accessToken özelliğini günceller ve yenilenen belirteci günlüğe kaydeder. Oturumu kapatma düğmesini etkinleştirerek işlemi tamamlar.

Oturumu kapatan kullanıcı

iOS için MSAL kullanarak iOS (Swift) uygulamanızdaki bir kullanıcının oturumunu kapatmak için aşağıdaki kodu kullanın:

   @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, applicationContext, currentAccountve webViewParametersvarlığını doğrular. Daha sonra, çıkış yapma sürecini günlüğe kaydeder. Kod, sağlanan hesabın önbellekteki tüm belirteçlerini kaldırır. Geçerli cihaz moduna bağlı olarak, tarayıcıdan oturumun kapatılıp kapatılmayacağını belirler. Tamamlandıktan sonra log metnini uygun şekilde güncelleştirir. Oturumu kapatma işlemi sırasında bir hata oluşursa, hata iletisini günlüğe kaydeder. Oturumu başarıyla kapattıktan sonra erişim belirtecini boş bir değere günceller ve mevcut hesabı temizler.

Sonraki adımlar