Dela via


Självstudie: Lägga till inloggning och utloggning i iOS/macOS-appen med inbyggd autentisering

Gäller för: Grön cirkel med en vit bockmarkeringssymbol. iOS (Swift) Grön cirkel med en vit bockmarkeringssymbol. macOS (Swift)

Den här självstudien visar hur du loggar in och loggar ut en användare med engångslösenord för e-post eller användarnamn och lösenord i din iOS/macOS-app med inbyggd autentisering.

I den här självstudien lär du dig att:

  • Logga in en användare med e-postlösenord eller användarnamn (e-post) och lösenord.
  • Logga ut en användare.
  • Hantera inloggningsfel

Förutsättningar

Logga in användare

Om du vill logga in en användare med flödet E-post engångslösenord samlar du in e-postmeddelandet och skickar ett e-postmeddelande som innehåller ett engångslösenord för användaren för att verifiera deras e-post. När användaren anger ett giltigt engångslösenord loggar appen in dem.

Om du vill logga in en användare med e-post med lösenordsflödet samlar du in e-postmeddelandet och lösenordet. Om användarnamnet och lösenordet är giltiga loggar appen in användaren.

Om du vill logga in på en användare måste du:

  1. Skapa ett användargränssnitt (UI) för att:

    • Samla in ett e-postmeddelande från användaren. Lägg till validering i dina indata för att se till att användaren anger en giltig e-postadress.
    • Samla in ett lösenord om du loggar in med användarnamn (e-post) och lösenord.
    • Samla in ett engångslösenord för e-post från användaren om du loggar in med engångslösenord för e-post.
    • Lägg till en knapp så att användaren kan skicka engångslösenordet igen om du loggar in med e-postlösenord för engångslösenord.
  2. I användargränssnittet lägger du till en knapp vars select-händelse startar en inloggning enligt följande kodfragment:

        @IBAction func signInPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "email not set"
            return
        }
    
        nativeAuth.signIn(username: email, delegate: self)
    }
    

    Om du vill logga in en användare med e-postflöde för engångslösenord använder vi följande kodfragment:

    nativeAuth.signIn(username: email, delegate: self)
    

    Metoden signIn(username:delegate) , som svarar asynkront genom att anropa någon av metoderna för det överförda ombudsobjektet, måste implementera SignInStartDelegate protokollet. Vi skickar den e-postadress som användaren anger i formuläret för e-postöverföring och skickas self som ombud.

    För att logga in en användare med e-post med lösenordsflöde använder vi följande kodfragment:

    nativeAuth.signIn(username: email, password: password, delegate: self)
    

    signIn(username:password:delegate) I metoden skickar du in den e-postadress som användaren angav för oss, deras lösenord och skickar det ombudsobjekt som överensstämmer SignInStartDelegate med protokollet. I det här exemplet skickar selfvi .

  3. Om du vill implementera SignInStartDelegate protokoll när du använder E-post engångslösenordflöde använder du följande kodfragment:

    extension ViewController: SignInStartDelegate {
        func onSignInStartError(error: MSAL.SignInStartError) {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCodeRequired(
            newState: MSAL.SignInCodeRequiredState,
            sentTo: String,
            channelTargetType: MSAL.MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    }
    

    Resultatet signIn(username:delegate) blir ett anrop till delegeringsmetoder. I det vanligaste scenariot onSignInCodeRequired(newState:sentTo:channelTargetType:codeLength) anropas för att indikera att en kod har skickats för att verifiera användarens e-postadress. Tillsammans med viss information om var koden har skickats och hur många siffror den innehåller, har den här delegatmetoden också en newState parameter av typen SignInCodeRequiredState, vilket ger oss åtkomst till följande två nya metoder:

    • submitCode(code:delegate)
    • resendCode(delegate)

    Använd submitCode(code:delegate) för att skicka engångslösenordet som användaren tillhandahåller i engångslösenordsformuläret med hjälp av följande kodfragment:

    newState.submitCode(code: userSuppliedCode, delegate: self)
    

    Accepterar submitCode(code:delegate) engångslösenordet och ombudsparametern. När du har skickat koden måste du verifiera engångslösenordet genom att implementera SignInVerifyCodeDelegate protokollet.

    Om du vill implementera SignInVerifyCodeDelegate protokoll som ett tillägg till klassen använder du följande kodfragment:

    extension ViewController: SignInVerifyCodeDelegate {
        func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
            resultTextView.text = "Signed in successfully."
            result.getAccessToken(delegate: self)
        }
    }
    

    I det vanligaste scenariot får vi ett anrop till onSignInCompleted(result) som anger att användaren har loggat in. Resultatet kan användas för att hämta access token.

    Accepterar getAccessToken(delegate) en delegatparameter och vi måste implementera de metoder som krävs i CredentialsDelegate protokollet.

    I det vanligaste scenariot får vi ett anrop till onAccessTokenRetrieveCompleted(result) som anger att användaren fick en access token.

    extension ViewController: CredentialsDelegate {
        func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) {
            resultTextView.text = "Error retrieving access token"
        }
    
        func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) {
            resultTextView.text = "Signed in. Access Token: \(result.accessToken)"
        }
    }
    
    
  4. Om du vill implementera SignInStartDelegate protokoll när du använder e-post med lösenordsflöde använder du följande kodfragment:

    extension ViewController: SignInStartDelegate {
        func onSignInStartError(error: MSAL.SignInStartError) {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
            // User successfully signed in
        }
    }
    

    I det vanligaste scenariot får vi ett anrop till onSignInCompleted(result) som anger att användaren har loggat in. Resultatet kan användas för att hämta access token.

    Accepterar getAccessToken(delegate) en delegatparameter och vi måste implementera de metoder som krävs i CredentialsDelegate protokollet.

    I det vanligaste scenariot får vi ett anrop till onAccessTokenRetrieveCompleted(result) som anger att användaren fick en access token.

    extension ViewController: CredentialsDelegate {
        func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) {
            resultTextView.text = "Error retrieving access token"
        }
    
        func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) {
            resultTextView.text = "Signed in. Access Token: \(result.accessToken)"
        }
    }
    
    

Hantera inloggningsfel

Under inloggningen lyckas inte alla åtgärder. Användaren kan till exempel försöka logga in med en e-postadress som inte finns eller skicka en ogiltig kod.

  1. Om du vill hantera fel i signIn(username) metoden eller signIn(username, password) använder du följande kodfragment:

    func onSignInStartError(error: MSAL.SignInStartError) {
        if error.isUserNotFound || error.isInvalidUsername {
            resultTextView.text = "Invalid username"
        } else {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    }
    
  2. Om du vill hantera fel i submitCode() metoden använder du följande kodfragment:

    func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) {
        if error.isInvalidCode {
            // Inform the user that the submitted code was incorrect and ask for a new code to be supplied
            let userSuppliedCode = retrieveNewCode()
            newState?.submitCode(code: userSuppliedCode, delegate: self)
        } else {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    }
    

    Om användaren anger en felaktig e-postverifieringskod innehåller felhanteraren en referens till en SignInCodeRequiredState som kan användas för att skicka en uppdaterad kod. I vår tidigare implementering av SignInVerifyCodeDelegate protokollet visade vi helt enkelt felet när vi hanterade onSignInVerifyCodeError(error:newState) delegatfunktionen.

Läs-ID-tokenanspråk

När appen har hämtat en ID-token kan du hämta anspråken som är associerade med det aktuella kontot. Om du vill göra det använder du följande kodfragment:

func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
   let claims = result.account.accountClaims
   let preferredUsername = claims?["preferred_username"] as? String
}

Nyckeln som du använder för att komma åt anspråksvärdet är det namn som du anger när du lägger till användarattributet som ett tokenanspråk.

Lär dig hur du lägger till inbyggda och anpassade attribut som tokenanspråk i artikeln Lägg till användarattribut till tokenanspråk .

Logga ut användare

Om du vill logga ut en användare använder du referensen MSALNativeAuthUserAccountResult till den som du fick i motringningen onSignInCompleted , eller använder getNativeAuthUserAccount() för att hämta ett loggat konto från cachen och lagra en referens i accountResult medlemsvariabeln.

  1. Konfigurera nyckelringsgruppen för projektet enligt beskrivningen här.

  2. Lägg till en ny medlemsvariabel i klassen ViewController : var accountResult: MSALNativeAuthUserAccountResult?.

  3. Uppdatera viewDidLoad för att hämta ett cachelagrat konto genom att lägga till den här raden när nativeAuth har initierats: accountResult = nativeAuth.getNativeAuthUserAccount().

  4. signInCompleted Uppdatera hanteraren för att lagra kontoresultatet:

    func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
        resultTextView.text = "Signed in successfully"
    
        accountResult = result
    }
    
  5. Lägg till en utloggningsknapp och använd följande kod för att logga ut användare:

    @IBAction func signOutPressed(_: Any) {
        guard let accountResult = accountResult else {
            print("Not currently signed in")
            return
        }
    
        accountResult.signOut()
    
        self.accountResult = nil
    
        resultTextView.text = "Signed out"
    }
    

Du har slutfört alla nödvändiga steg för att logga ut en användare i din app. Skapa och kör ditt program. Om allt är bra bör du kunna välja utloggningsknappen för att logga ut.

Konfigurera anpassad anspråksprovider

Om du vill lägga till anspråk från ett externt system i den token som utfärdas till din app använder du en anpassad anspråksprovider. En anpassad anspråksprovider består av ett anpassat autentiseringstillägg som anropar ett externt REST API för att hämta anspråk från externa system.

Följ stegen i Konfigurera en anpassad anspråksprovider för att lägga till anspråk från ett externt system i dina säkerhetstoken.